首页 平衡二叉树

平衡二叉树

举报
开通vip

平衡二叉树二叉树: 左子树都小于根节点,右子树都大于根节点。可以动态维护这棵树(因为是树结构,可以有限步完成插入),所以是动态查找算法。时间复杂度为O(logn)在46.5%的情况下,需要把二叉树平衡化成“平衡二叉树”。 平衡二叉树:定义:平衡二叉树或为空树,或为如下性质的二叉排序树: (1)左右子树深度之差的绝对值不超过1; (2)左右子树仍然为平衡二叉树. 平衡因子:平衡因子bf=左子树深度-右子树深度, 每个结点的平衡因子只能是1,0,-1。若其绝对值超过1,则该二叉排序树就是不平衡的。增加一个元素后,平衡二叉树有可...

平衡二叉树
二叉树: 左子树都小于根节点,右子树都大于根节点。可以动态维护这棵树(因为是树结构,可以有限步完成插入),所以是动态查找算法。时间复杂度为O(logn)在46.5%的情况下,需要把二叉树平衡化成“平衡二叉树”。 平衡二叉树:定义:平衡二叉树或为空树,或为如下性质的二叉排序树: (1)左右子树深度之差的绝对值不超过1; (2)左右子树仍然为平衡二叉树. 平衡因子:平衡因子bf=左子树深度-右子树深度, 每个结点的平衡因子只能是1,0,-1。若其绝对值超过1,则该二叉排序树就是不平衡的。增加一个元素后,平衡二叉树有可能变成不平衡了,所以需要旋转平衡调整。 平衡二叉树算法思想: 若向平衡二叉树中插入一个新结点后破坏了平衡二叉树的平衡性。首先要找出插入新结点后失去平衡的最小子树根结点的指针。然后再调整这个子树中有关结点之间的链接关系,使之成为新的平衡子树。当失去平衡的最小子树被调整为平衡子树后,原有其他所有不平衡子树无需调整,整个二叉排序树就又成为一棵平衡二叉树。失去平衡的最小子树是指以离插入结点最近,且平衡因子绝对值大于1的结点作为根的子树。假设用A 关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf 示失去平衡的最小子树的根结点,则调整该子树的操作可归纳为下列四种情况:(可以断定插入一个节点一定是在叶子节点上) (1)LL型平衡旋转法 由于在A的左孩子B的左子树上插入结点F,使A的平衡因子由1增至2而失去平衡。故需进行一次顺时针旋转操作。 即将A的左孩子B向右上旋转代替A作为根结点,A向右下旋转成为B的右子树的根结点。而原来B的右子树则变成A的左子树。 (2)RR型平衡旋转法 由于在A的右孩子C 的右子树上插入结点F,使A的平衡因子由-1减至-2而失去平衡。故需进行一次逆时针旋转操作。即将A的右孩子C向左上旋转代替A作为根结点,A向左下旋转成为C的左子树的根结点。而原来C的左子树则变成A的右子树。 (3)LR型平衡旋转法 由于在A的左孩子B的右子数上插入结点F,使A的平衡因子由1增至2而失去平衡。故需进行两次旋转操作(先逆时针,后顺时针)。即先将A结点的左孩子B的右子树的根结点D向左上旋转提升到B结点的位置,然后再把该D结点向右上旋转提升到A结点的位置。即先使之成为LL型,再按LL型处理。 如图中所示,即先将圆圈部分先调整为平衡树,然后将其以根结点接到A的左子树上,此时成为LL型,再按LL型处理成平衡型。 (4)RL型平衡旋转法   由于在A的右孩子C的左子树上插入结点F,使A的平衡因子由-1减至-2而失去平衡。故需进行两次旋转操作(先顺时针,后逆时针),即先将A结点的右孩子C的左子树的根结点D向右上旋转提升到C结点的位置,然后再把该D结点向左上旋转提升到A结点的位置。即先使之成为RR型,再按RR型处理。 如图中所示,即先将圆圈部分先调整为平衡树,然后将其以根结点接到A的左子树上,此时成为RR型,再按RR型处理成平衡型。 平衡化靠的是旋转。参与旋转的是3个节点(其中一个可能是外部节点NULL),旋转就是把这3个节点转个位置。 注意的:左旋的时候p->right一定不为空,右旋的时候p->left一定不为空,这是显而易见的。 如果从空树开始建立,并时刻保持平衡,那么不平衡只会发生在插入删除操作上,而不平衡的标志就是出现bf == 2或者 bf == -2的节点。 插入和删除 : 插入删除是互为镜像的操作。我们可以采用前面对二叉排序树的删除操作来进行。然后,在删除掉结点后,再对平衡树进行平衡化处理。删除之所以删除操作需要的平衡化可能比插入时次数多,就是因为平衡化不会增加子树的高度,但是可能会减少子树的高度,在有有可能使树增高的插入操作中,一次平衡化能抵消掉增高;在有可能使树减低的删除操作中,平衡化可能会带来祖先节点的不平衡。AVL树体现了一种平衡的美感,两种旋转是互为镜像的,插入删除是互为镜像的操作,没理由会有那么大的差别。实际上,平衡化可以统一的这样来操作: 查找:先按关键字找到删除的节点*p 删除:分为:1.叶子节点:直接删除该节点 2.单分子节点:用*p节点的左边或右孩子节点替代*p 3.双分子节点:用*p节点的左子树的最右下节点*r的值替代*p节点值,用*p 节点的右子数的最左下节点*r的值替代*p节点的值,再删除*r节点 调整: 1、while (current != NULL)修改current的平衡因子。 (1)插入节点时current->bf += (current->data > *p)?1:-1; (2)删除节点时current->bf -= (current->data > *p)?1:-1; (3)current指向插入节点或者实际删除节点的父节点,这是普通二叉搜索树的插入和删除操作带来的结果。*p初始值是插入节点或者实际删除节点的data。因为删除操作可能实际删除的不是data。 2、判断是否需要平衡化 if (current->bf == -2)     L_Balance(c_root); else if (current->bf == 2)  R_Balance(c_root); 3、是否要继续向上修改父节点的平衡因子 (1)插入节点时if (!current->bf) break;这时,以current为根的子树的高度和插入前的高度相同。 (2)删除节点时if (current->bf) break;这时,以current为根的子树的高度和删除前的高度相同 4、当前节点移动到父节点,转1。 p = &(current->data); current = current->parent; 习题分析: 1.含有n个节点的平衡二叉树的最大高度为O(log2n) 2.设Nh表示高度为h的平衡二叉树中含有的最少节点数:有N1=1、N2=2、Nh=Nh-1+Nh-2+1 3.已知节点个数N,有N1=1、N2=2、Nh=Nh-1+Nh-2+1,可以求出树的最大高度, 4.在一棵高度为h(h≧3)的平衡二叉树,最小叶子节点所在层次为h,最小叶子节点所在层次为min(h),显然有,min(1)=1,min(2)=2,min(1)={min(h-1),min(h-2)}+1 5.查找比较关键字序列:设含有n个节点的平衡二叉树,1.求出其最大高度,和叶子节点最小层数,则比较次数最大为最大高度值其一定能找到该节点(存在),所以序列个数一定小于最大高度大于或等于叶子节点最小层数  2.符合二叉排序树排序,用此排除一些选项 五、相关代码实现 1.基本结构体及变量 #define LH +1  // 左高 #define EH 0    // 等高 #define RH -1  // 右高 // 平衡二叉树的类型 struct AVLNode { int data; int bf;    //bf结点的平衡因子,只能够取0,-1,1,为左子树的深度减去右子树的深度 struct AVLNode *lchild,*rchild;    // 左、右孩子指针 }; 2.右旋操作: void R_Rotate(AVLNode *&p)  // LL型算法 { AVLNode *lc=p->lchild; // lc指向p的左子树根结点 p->lchild=lc->rchild; // lc的右子树挂接为p(之前跟节点)的左子树 lc->rchild=p; p=lc;                  // p指向新的根结点 } 3.左旋操作: void L_Rotate(AVLNode *&p)  // RR型算法 { AVLNode *rc=p->rchild;    // rc指向p的右子树根结点 p->rchild=rc->lchild;    // rc的左子树挂接为p的右子树 rc->lchild=p; p=rc;                    // p指向新的根结点 } 4.对树进行左平衡操作: void LeftBalance(AVLNode *&T) {  AVLNode *lc,*rd; lc=T->lchild;                      // lc指向T的左子树根结点 switch(lc->bf)    //  1为左高、0等高、-1为右高 { case LH:              // 1 新结点插入在*T的左孩子的左子树上,要作单右旋处理 T->bf=lc->bf=EH; R_Rotate(T); break; case RH:                // -1 新结点插入在*T的左孩子的右子树上,要作双旋处理 rd=lc->rchild;                // rd指向*T的左孩子的右子树根 switch(rd->bf) {        // 根据旋转后的效果去修改T及其左孩子的平衡因子 以下右旋转类似 case LH: T->bf=RH; lc->bf=EH; break; case EH: T->bf=lc->bf=EH; break; case RH: T->bf=EH; lc->bf=LH; } rd->bf=EH; L_Rotate(T->lchild);          R_Rotate(T);                } } 5.对树进行右平衡操作: void RightBalance(AVLNode *&T)
本文档为【平衡二叉树】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_260251
暂无简介~
格式:doc
大小:28KB
软件:Word
页数:0
分类:
上传时间:2019-09-02
浏览量:56