二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。二叉搜索树作为一种经典的数据结构,它既有链表的快速插入与删除操作的特点,又有数组快速查找的优势;所以应用十分广泛,例如在文件系统和数据库系统一般会采用这种数据结构进行高效率的排序与检索操作。
二叉树ADT
从定义二叉树的常规内容开始,该定义假设树中不包含相同的项目,很多操作与列表操作相同。不同之处在于数据的层次性安排。
二叉搜索树是能够高效地进行如下操作的数据结构。
1.插入一个数值
2.查询是否包含某个数值
3.删除某个数值
下面是有关此ADT的非正式总结
类型名称 | 二叉搜索树 |
---|---|
类型属性: | 二叉树或者是一个空的节点集合(空树),或者是一个指定某一节点为根的节点集合 |
每个节点有两个作为其后代的树,称为左子树和右子树 | |
每一个子树本身又是一个二叉树,也包含它是个空树的可能性 | |
二叉搜索树是有序的二叉树,它的每个节点也包含一个项目,它的左子树的项目排在根项目的前面,而跟项目在所有右子树项目的前面 | |
类型操作: | 把树初始化为空树 |
确定树是否为空 | |
确定树是否已满 | |
确定树中项目的个数 | |
向树中添加一个项目 | |
向树中删除一个项目 | |
在树中搜索一个项目 | |
访问树中一个项目 | |
清空树 |
二叉搜索树的接口
1 | /* tree.h -- 二叉搜索树 */ |
二叉搜索树的实现
添加项目步骤
- 判断树是否已满,添加的项目重复
- 创建新节点
- 若根节点为NULL,则新节点为根节点,否则调用AddNode()函数
添加节点步骤(AddNode)
- 判断添加的节点项目大于(小于)当前根节点
- 判断左(右)子树为空
- 若左(右)子树为空,添加新节点,否则递归调用AddNode,即回到第一步
删除项目步骤
- 调用SeekItem查找要删除的目标函数,返回一个结构体地址(包含目标项目的节点和其根节点)
- 如果返回的节点为空,说明未找到目标项目。
- 判断其节点位置(左/右子树或根),调用 DeleteNode()
- 项目减一
删除节点步骤(DeleteNode)
- 创建一个临时节点
- 若目标节点的左(右)节点为空/无节点,保存节点信息,右(左)节点取代父节点位置,释放节点
- 若目标节点的含有两个节点,循环,沿着左子树的最右分支查找空位置
- 把目标节点的右子树放到(依附)目标节点左子树的右分支空位置
- 左子树取代目标节点位置,释放目标节点
1 | /* tree.c -- 树类型的支持函数 */ |
二叉搜索树的应用
1 | /* petclub.c -- 使用二叉树 */ |