1、第9章 查找,数据结构讲义,- 二叉树和平衡二叉树,特点:,一、二叉排序树的定义 二、二叉排序树的插入与删除 三、二叉排序树的查找分析 四、平衡二叉树 五、B-树和B+树,9.2 动态查找表,表结构在查找过程中动态生成。,要求:,对于给定值key, 若表中存在其关键字等于key的记录,则查找成功返回; 否则插入关键字等于key 的记录。,典型的动态表二叉排序树,一、二叉排序树的定义,练:下列2种图形中,哪个不是二叉排序树 ?,-或是一棵空树;或者是具有如下性质的非空二叉树:(1)左子树的所有结点均小于根的值;(2)右子树的所有结点均大于根的值;(3)它的左右子树也分别为二叉排序树。,讨论:对(
2、a)中序遍历后的结果是什么?,二、二叉排序树的插入与删除,将数据元素构造成二叉排序树的优点: 查找过程与顺序结构有序表中的折半查找相似,查找效率高; 中序遍历此二叉树,将会得到一个关键字的有序序列(即实现了排序运算); 如果查找不成功,能够方便地将被查元素插入到二叉树的叶子结点上,而且插入或删除时只需修改指针而不需移动元素。,注:若数据元素的输入顺序不同,则得到的二叉排序树形态也不同!,这种既查找又插入的过程称为动态查找。 二叉排序树既有类似于折半查找的特性,又采用了链表存储,它是动态查找表的一种适宜表示。,45,如果待查找的关键字序列输入顺序为: (24,53, 45,45,12,24,90
3、),,24,讨论1:二叉排序树的插入和查找操作,则生成二叉排序树的过程为:,例:输入待查找的关键字序列=(45,24,53,45,12,24,90),则生成的二叉排序树形态不同:,二叉排序树的查找&插入算法如何实现?,查找算法,静态查找算法,动态查找算法(插入),二叉排序树的静态查找思想,若二叉排序树为空,则查找失败. 否则,先拿根结点值与待查值进行比较,若相等,则查找成功. 若根结点值大于待查值,则进入左子树重复此步骤,否则,进入右子树重复此步骤.,二叉排序树查找的算法实现,1)递归函数 NODE *search(t,x)NODE *t;char x;if(t=NULL)return(NUL
4、L);elseif(t-data=x)return(t);if(xdata)return(search(t-lchild,x);else return(search(t-lchild,x); ,2)非递归函数NODE *search(NODE *t,char x)NODE *p;p=t;while(p!=NULL)if(p-data=x)return(p);if(xdata)p=p-lchild;else p=p-rchlid; printf(“ 找不到值为%x的结点!”,x);return(NULL);,二叉排序树的动态查找算法,查找算法:若二叉排序树为空,则返回插入位置,否则,先拿根结点值
5、与待查值进行比较,若相等,则查找成功,若根结点值大于待查值,则进入左子树重复此步骤,否则,进入右子树重复此步骤。(P228算法9.5(b) 插入算法:若二叉排序树为空,则被查结点为新的根节点;否则,作为一个新的叶子结点插入在由查找返回的位置上。(P228算法9.6),二叉排序树的建立 对于已给定一待排序的数据序列,通常采用逐步插入结点的方法来构造二叉排序树,即只要反复调用二叉排序树的插入算法即可,算法描述为: BiTree *Creat (int n) /建立含有n个结点的二叉排序树 BiTree *BST= NULL;for ( int i=1; i=n; i+) scanf(“%d”, ,
6、二叉排序树的删除 要删除二叉排序树中的p结点,分三种情况: p为叶子结点,只需修改p双亲f的指针。 p只有左子树或右子树,只需用p的孩子代替p。 p左、右子树均非空。沿p左子树的根C的右子树分支找到S,S的右子树为空。 法1:令*p的左子树为 *f的左子树,*p的右子树为*s的右子树; 法2:令*s代替*p 将S的左子树成为S的双亲Q的右子树,用S取代p 。 若C无右子树,用C取代p。,法2:,法1:,例:请从下面的二叉排序树中删除结点P。,S,1) 二叉排序树上查找某关键字等于给定值的结点过程,其实就是走了一条从根到该结点的路径。比较的关键字次数此结点的层次数;最多的比较次数树的深度(或高度
7、),即 log2 n+12) 一棵二叉排序树的平均查找长度为:,三、二叉排序树的查找分析,其中: ni 是每层结点个数; Ci 是结点所在层次数; m 为树深。,最坏情况:即插入的n个元素从一开始就有序,变成单支树的形态!此时树的深度为n ; ASL= (n+1)/2 此时查找效率与顺序查找情况相同。,最好情况:即:与折半查找中的判定树相同(形态比较均衡),3)对有 n 个关键字的二叉排序树的平均查找长度:设每种树态出现概率相 同 ,查找每个关键字也是等概率的。 则ASL求解过程可推导。(详见教材P232),树的深度为:log 2n +1 ; ASL=log 2(n+1) 1 ;与折半查找相同
8、。,结论:二叉排序树的ASL2(11/n)ln n,四、平衡二叉树,平衡二叉树又称AVL树,它是具有如下性质的 二叉树:,为了方便起见,给每个结点附加一个数字,给 出该结点左子树与右子树的高度差。这个数字 称为结点的平衡因子balance。这样,可以得到 AVL树的其它性质:,即|左子树深度-右子树深度| 1,左、右子树是平衡二叉树; 所有结点的左、右子树深度之差的绝对值 1,(a) 平衡树 (b) 不平衡树,例:判断下列二叉树是否AVL树?,任一结点的平衡因子只能取:-1、0 或 1;如果树中任意一个结点的平衡因子的绝对值大于1,则这棵二叉树就失去平衡,不再是AVL树;,对于一棵有n个结点的
9、AVL树,其高度保持在O(log2n)数量级,ASL也保持在O(log2n)量级。,1,1,-1,-1,2,1,-1,如果在一棵AVL树中插入一个新结点,就有可能造成失衡,此时必须重新调整树的结构,使之恢复平衡。我们称调整平衡过程为平衡旋转。,现分别介绍这四种平衡旋转。,平衡旋转可以归纳为四类:LL平衡旋转RR平衡旋转LR平衡旋转RL平衡旋转,若在A的左子树的左子树上插入结点,使A的平衡因子从1增加至2,需要进行一次顺时针旋转。 (以B为旋转轴),若在A的右子树的右子树上插入结点,使A的平衡因子从-1增加至-2,需要进行一次逆时针旋转。 (以B为旋转轴),2)RR平衡旋转:,1)LL平衡旋转:
10、,若在A的右子树的左子树上插入结点,使A的平衡因子从-1增加至-2,需要先进行顺时针旋转,再逆时针旋转。 (以插入的结点C为旋转轴),4)RL平衡旋转:,若在A的左子树的右子树上插入结点,使A的平衡因子从1增加至2,需要先进行逆时针旋转,再顺时针旋转。 (以插入的结点C为旋转轴),3)LR平衡旋转:,这种调整规则可以保证二叉排序树的次序不变,5,3,6,2,4,1,3,2,5,1,6,4,5,2,6,1,4,3,4,2,5,1,6,3,2,1,4,3,5,6,4,2,5,1,6,3,2,1,5,4,6,3,4,2,5,1,6,3,例:请将下面序列构成一棵平衡二叉排序树: ( 13,24,37,
11、90,53),0 13,-1 13,-1 24,-2 13,需要RR平衡旋转 (绕B逆转,B为根),-1 24,-1 37,1 90,-2 37,需要RL平衡旋转 (绕C先顺后逆),作业,已知如下所示长度为12的表: (Jan, Feb, Mar, Apr, May, June, July, Aug, Sep, Oct, Nov, Dec) (1) 试按表中元素的顺序依次插入一棵初始为空的二叉排序树,画出插入完成之后的二叉排序树,并求其在等概率的情况下查找成功的平均查找长度。 (2) 若已经对表中元素进行排序构成有序表,求在等概率的情况下对此有序表进行折半查找时查找成功的平均查找长度。 (3) 按表中元素顺序构造一棵平衡二叉排序树,画出每插入一个元素的示意图并标明类型(LL,RR,LR,RL),并求其在等概率的情况下查找成功的平均查找长度。,