当前位置:
文档之家› DS06数据结构树-二叉排序树.ppt
DS06数据结构树-二叉排序树.ppt
Aug July
Sept
Oct Dec
Nov
第4章 树
§4.4二叉搜索树
• 对于一个无序序列可以通过构造一棵BST树而变成一个有 序序列。
• 由算法知,每次插入的新结点都是BST树的叶子结点,即 在插入时不必移动其它结点,仅需修改某个结点的指针。
• 利用BST树的插入操作,可以从空树开始逐个插入每个结 点,从而建立一棵BST树.
Tmp = FindMin( BST->Right ); //在右子树中找最小的元素填充删除结点
BST->Data = Tmp->Data;
BST->Right = Delete( BST->Data, BST->Right); //在删除结点的右子树中删除最小元素
} else { //被删除结点有一个或无子结点
return BST; }
代码4.17 查找最大元素的迭代函数
第4章 树
§4.4二叉搜索树
❖ 二叉搜索树的插入
〖分析〗将元素X插入二叉搜索树BST中关键是要找到元素应该插 入的位置。位置的确定可以利用与查找函数Find类似的方法,如果 在树BST中找到X,说明要插入的元素已存在,可放弃插入操作。 如果没找到X,查找终止的位置就是X应插入的位置。
➢ 最大元素一定是在树的最右分枝的端结点上 ➢ 最小元素一定是在树的最左分枝的端结点上
18
最左端点
10
20
7
15
22
9
§4.4二叉搜索树 最右端点
第4章 树
§4.4二叉搜索树
Position FindMin( BinTree BST ) {
if( !BST ) return NULL; //空的二叉搜索树,返回NULL else if( !BST->Left )
return Find( X, BST->Right ); //在右子树中继续查找 else if( X < BST->Data )
return Find( X, BST->Left ); //在左子树中继续查找 else //X == BST->Data
return BST; //查找成功,返回找到结点的地址 }
如果根结点的键值大于X,接下来的搜索将在左子树中进 行;
若两者比较结果是相等,搜索完成,返回指向此结点的指 针。
第4章 树
❖ 二叉搜索树的查找操作Find
§4.4二叉搜索树
Position Find( ElementType X, BinTree BST ) {
if( !BST ) return NULL; //查找失败 if( X > BST->Data )
Jan
Feb
Mar
Apr
June May
Aug
July
Dec
Sept Oct
July
Feb
May
Apr Aug
Aug
Jan
Mar Oct
Apr Dec
June Nov Sept
Nov
深度:㏒2n +1~n
Oct Sept
第4章 树
§4.4二叉搜索树
❖ 二叉搜索树的删除
➢ 二叉搜索树的删除操作比其它操作更为复杂,有三种情况需要考虑:
BST->Left = Insert( X, BST->Left); //递归插入左子树
else if( X > BST->Data ) BST->Right = Insert( X, BST->Right); //递归插入右子树
// else X已经存在,什么都不做 return BST;
}
代码4.18 二叉搜索树的插入算法
第4章 树
❖ 二叉搜索树的查找操作Find
§4.4二叉搜索树
➢ 查找从根结点开始,如果树为空,返回NULL,表示 未找到关键字为X的结点。
➢ 若搜索树非空,则根结点关键字和X进行比较,依据 比较结果,需要进行不同的处理:
若根结点键值小于X,满足条件的结点将不会出现在它的 左子树,接下来的搜索只需在右子树中进行;
优点:查找效率高
缺点:要求线性表有序,如果是进行动态查找,即需要对线性表进行 插入、删除或排序操作,就必须移动大量的记录,当记录数很多时, 这种移动的代价很大。
第4章 树
❖ 11个元素的二分查找判定树
§4.4二叉搜索树
6
3
9
1
4
7 10
2
5
8
11
➢判定树的特点: ➢ 左子树的值都比根结点小 ➢ 右子树的值都比根结点大
➢ 中序遍历判定树得到的是一组有序 的序列
11个元素的判定树
➢能否根据以上特点,利用树型结构来动 态创建查找表呢?
第4章 树
❖二叉搜索树
§4.4二叉搜索树
“二叉搜索树(BST,Binary Search Tree)”也称二叉排序树 或二叉查找树,它是一种对排序和查找都很有用的特殊二叉树。
【定义】一个二叉搜索树是一棵二叉树,它可以为空。如果不为空,
Tmp = BST; if( !BST->Left ) // 有右孩子或无子结点
BST = BST->Right; else if( !BST->Right ) //有左孩子或无子结点
BST = BST->Left;
free( Tmp );
}
return BST;
}
第4章 树
❖二叉树排序树性能
§4.5 平衡二叉树
它将满足以下性质:
1.非空左子树的所有键值小于其根结点的键值。
2.非空右子树的所有键值大于其根结点的键值。
3.左、右子树都是二叉搜索树。
6
18
3
9
30
10
20
15 1
441 7 10
7
5
22
233 5 50 8
11
11个元素二分查找的判定树
第4章 树
§4.4二叉搜索树
❖ 二叉搜索树的动态查找
typedef Position BinTree
Jan
Feb Apr
Mar June May
Aug
July
Dec
Sept Oct
Nov
July
Feb
May
Apr Aug
Aug Jan Apr Dec
Mar Oct June Nov Sept
Oct Sept
第4章 树
§4.5 平衡二叉树
➢ 按ASL的定义,可以分别计算出三棵二叉搜索树的平均查找长度: ASL(a)=(1+2×2+3×3+4×3+5×2+6×1)/12 = 3.5; ASL(b)=(1+2×2+3×4+4×5)/12 = 3.0; ASL(c)=(1+2×1+3×1+4×1+5×1+6×1+7×1+8×1+9×1+10×1+11 ×1+12×1)/12 = 6.5;
第4章 树
§4.4二叉搜索树
【例4.8】以一年十二个月的英文缩写为键值,按从一月到十二月顺序 输入它们,即输入序列为(Jan, Feb, Mar, Apr, May, Jun, July, Aug, Sep, Oct, Nov, Dec),将产生什么样的二叉搜索树?
Jan
FebMarBiblioteka AprJun May
查找二叉搜索树(BST)的时间复杂度(最坏情况下) 用查找过程中的比较次数来衡量,它取决于树的深度。
〖例〗不同的插入次序,将导致不同的深度和平均查找长度ASL。 (a) 按一月到十二月的自然月份序列输入所生成的; (b) 输入序列为(July, Feb, May, Mar, Aug, Jan, Apr, Jun, Oct, Sept, Nov, Dec) (c) 输入序列则是按月份字符串从小到大的顺序排列的。
要删除的是叶结点——可以直接删除,然后再修改其父结点的指针。
〖例〗:删除 35
30
15 要删除结点
41
33
50
35
图4.28 二叉搜索树叶结点的删除
第4章 树
§4.4二叉搜索树
要删除的结点只有一个孩子结点——删除之前需要改变其父结点的
指针,指向要删除结点的孩子结点。
〖例〗:删除 33
30
15
41
else if( X < BST->Data ) BST->Left = Delete( X, BST->Left); // 左子树递归删除
else if( X > BST->Data ) BST->Right = Delete( X, BST->Right); // 右子树递归删除
else //找到要删除的结点 if( BST->Left && BST->Right ) { //被删除结点有左右两个子结点
➢ 二叉搜索树作为抽象数据结构的定义与普通二叉树相同,但操作集 中多了下列几个特别的函数:
Position Find( ElementType X, BinTree BST ):从二叉搜索树BST
中查找元素X,返回其所在结点的地址;
Position FindMin( BinTree BST ):从二叉搜索树BST中查找并返回
• 思考:用上述方法构造的含有n个结点BST树,其深度是多少?
深度:㏒2n +1~n
第4章 树
§4.5 平衡二叉树
〖例〗不同的插入次序,将导致不同的深度。