定义
二叉排序树或者非空二叉树,或者为具有以下性质的二叉树:
1、若根结点的左子树不空,则左子树上所有结点的值都小于根结点的值;
2、若根结点的右子树不空,则右子树上所有结点的值都大于或者等于根结点的值;
每一棵子树分别也是二叉排序树。
上述定义为递归定义
如下图:
该二叉树的中序序列如下:
10, 30, 35, 38, 40, 50, 50, 58, 60, 64, 70, 73, 100
我们发现二叉排序树的中序序列从小到大递增;
二叉排序树的建立
逐点插入法
设K=( k1,k2,k3, …, kn)为具有n 个数据元素的序列。从序列的第一个元素开始,依次取序列中的元素,每取一个元素ki,按照下述原则将ki 插入到二叉树中:
1、若二叉树为空,则ki 作为该二叉树的根结点;
2、若二叉树非空,则将ki 与该二叉树的根结点的值进行比较;若ki 小于根结点的值,则将ki插入到根结点的左子树中:否则,将ki 插入到根结点的右子树中。
3、将ki 插入到左子树或者右子树中仍然遵循上述原则。
建立二叉排序树的(主)算法
建立二叉排序树的(主)算法的C语言实现如下:
主算法很简单,循环调用每个节点的插入算法。其中,插入一个节点的非递归算法如下:
二叉排序树的删除
二叉排序树的删除原则如下:
1、被删除结点为叶结点,则直接删除;
2、被删除结点无左子树,则用右子树的根结点取代被删除结点;
3、被删除结点无右子树,则用左子树的根结点取代被删除结点;
4、被删除结点的左、右子树都存在,则用被删除结点的右子树中值最小的结点(或被删除结点的左子树中值最大的结点)取代被删除结点。
二叉排序树的查找
二叉排序树的查找过程
二叉排序树的查找过程如下:
若二叉排序树为空,则查找失败,结束。
若二叉排序树非空,则将被查找元素与二叉排序树的根结点的值进行比较,
1、若等于根结点的值,则查找成功,返回被查到元素所在链结点的地址,查找结束;
2、若小于根结点的值,则到根结点的左子树中重复上述查找过程;
3、若大于根结点的值,则到根结点的右子树中重复上述查找过程;
直到查找成功或者失败。
该过程是一个递归过程;由于查找过程和插入过程很相像,所以二叉排序树也叫二叉查找树。
同时做如下约定:
1、若查找成功,给出被查找元素所在结点的地址;
2、若查找失败,给出信息NULL;
3、二叉树采用二叉链表存储结构。
查找算法
二叉排序树的查找算法如上所述,该算法可以使用递归实现,也可以不使用。
递归实现查找算法
递归算法易于理解,但是效率较低。
非递归实现查找算法
非递归算法不易于理解,但是效率较高。
查找效率
二叉排序树的查找效率可以用平均查找长度ASL来评估
ASL定义如下:
平均查找长度ASL —— 确定一个元素在树中位置所需要进行的元素间的比较次数的期望值(平均值),计算公式如下:
其中:
1、n表示二叉树中结点的总数;
2、pi表示查找第i个元素的概率;
3、ci表示查找第i个元素需要进行的元素之间的比较次数。以如下二叉排序树为例,其ASL计算过程如下:
ASL的计算方法如下:
第一层元素个数 *1 + 第二层元素个数 *2 + 第三层元素个数 *3+……+第n层元素个数 *n 。
可以利用二叉树的按层遍历,然而将每层的元素个数乘以第几层。
注:
如果被插入的元素序列是随机序列,或者序列的长度较小,采用逐点插入法建立二叉排序树可以接受。如果建立的二叉排序树中出现结点子树的深度之差较大时(即产生不平衡),就有必要采用其他方法建立二叉排序树,即建立所谓“平衡二叉树”。
比较理想的情况下,二叉排序树查找的时间复杂度为O(log2n),当出现“退化二叉树”时,时间复杂度为O(n)。