二叉排序树的定义
二叉排序树或者是一棵空树,或者是具有下列性质的二叉树:
- 左子树上所有结点的值均小于根结点的值;
- 右子树的所有结点的值均大于根结点的值;
- 他的左右子树也分别都是二叉排序树;
二叉排序树的查找过程
- 首先和根结点的值进行比较,若相等,则返回成功,返回结点位置
- 若小于根节点的值,则继续在其左子树上查找;
- 若大于根结点的值,则继续在其右子树上查找;
- 直至查找成功或者查找失败。
查找成功:走了一条从二叉排序树的根到对应结点的路径。
查找失败:从二叉排序树的根到路径末端。
二叉排序树的插入
- 查找失败时,插入新结点。
- 新结点为查找失败时查找路径上访问的最后一个结点的左孩子或右孩子,只需要修改指针;
- 新结点为叶子结点。
二叉排序树的建立
在查找过程中建立,初始为空二叉树,每次查询失败时,就插入新结点。
注意:二叉排序树在不断变化,且数据元素的输入顺序不同,得到的二叉排序树形态也不同。
二叉排序树的删除
删除需要视情况而定:
-
如果要删除的
*p
为叶子:删除此结点时,修改*f
(*p
的双亲)的lchild或者rchild为null; -
*p
只有一棵子树(或左或右):令PL或者PR代替*p
称为*f
的孩子;
3.*p
有两棵子树:
设删除前中序遍历的序列为:...S P PR....//P的直接前驱是s
希望删除P后,其他元素的相对位置不变。
如图所示:要删除P结点,且要保持删除后依然为AVL有两种方法:
-
令
*p
的左子树代替*p
成为f的左子树,*p
的右子树为s的右子树;
-
令
*s
代替*p
(以*p
的直接前驱或者直接后继代替他)//*s为*p
左子树最右下的结点
-
二叉排序树查找分析
二叉排序树上查找某关键字等于给定值得结点过程,其实就是走了一条从根到该结点的路径。
二叉排序树的平均查找长度
其中ni是每层结点的个数;
Ci是结点所在的层次;
m为树高度。
最好情况:与折半查找中的判定树相同(形态比较均衡),即高度等于具有相同结点数的完全二叉树的高度
最坏情况:即插入的n个元素从一开始就有序,一变成单支树的形态!
( 此时树的深度为n;
ASL= (n+1)/2
查找效率与顺序查找情况相同。
)