【平衡二叉树的平衡调整-----------理论】

1平衡二叉树的基本概念

1.1回顾二叉排序树的查找

在这里插入图片描述
由于形态不均匀的二叉排序树查找效率不高,为了解决这个问题,我们引入了平衡二叉树

1.2平衡二叉树的定义

在这里插入图片描述

1.3平衡二叉树的 平衡因子(BF)

在这里插入图片描述
在这里插入图片描述
分为3种情况:
根据平衡二叉树的定义,平衡二叉树上所有结点的平衡因子只能是以下三种情况
-1:结点左子树的高度 小于 结点右子树的高度
0:结点左子树的高度 等于 结点右子树的高度
1:结点左子树的高度 大于 结点右子树的高度

以下是两个实例:
在这里插入图片描述
计算如下:
在这里插入图片描述

在这里插入图片描述

2.平衡调整方法:

当我们在一个平衡二叉排序树上插入一个结点时有可能导致失衡,即出现平衡因子绝对值大于1的结点,如:2、-2.

比如:
在这里插入图片描述
如果在一颗AVL树中插入一个新结点后造成失衡,则必须重新调整树的结构,使之恢复平衡

2.1平衡调整的四种类型:

2.1.1引入:

在这里插入图片描述
如上图所示:

A:失衡结点不止一个失衡结点时,为最小失衡子树的根结点
(比如右边那棵树:结点7开始的失衡子树共有5个结点,而从16开始的失衡子树共有3个结点,此时失衡结点为16)

B: A(失衡结点)的孩子,C(新插入结点的双亲)
C: 插入新结点的子树新插入的结点是C结点

2.1.2平衡调整的四种类型 与手动计算调平后的失衡子树结构:

在这里插入图片描述

2.1.2.1 根据A、B、C的关系确定失衡类型

LL(Left-Left)型失衡

  • 描述:在插入或删除节点后,新插入的节点位于失衡节点的左孩子的左子树上(可以是失衡结点左子树的左子树旳根),导致该失衡节点左子树比右子树高2
  • 解决:通过一次右旋操作来恢复平衡。

RR(Right-Right)型失衡
描述:在插入或删除节点后,新插入的节点位于失衡节点的右孩子的右子树上(可以是失衡结点左子树的左子树旳根),导致该失衡节点右子树比左子树高2。
解决:通过一次左旋操作来恢复平衡。

LR(Left-Right)型失衡

  • 描述:在插入或删除节点后,新插入的节点位于失衡节点的左孩子的右子树上(可以是失衡结点左子树的右子树旳根),导致该失衡节点的左子树比右子树高1。
  • 解决:首先对失衡节点的左子节点进行左旋操作,然后对失衡节点进行右旋操作来恢复平衡。

RL(Right-Left)型失衡

  • 描述:在插入或删除节点后,新插入的节点位于失衡节点的右孩子的左子树上(可以是失衡结点右子树的左子树旳根),导致该失衡节点的右子树比左子树高1。
  • 解决:首先对失衡节点的右子节点进行右旋操作,然后对失衡节点进行左旋操作来恢复平衡。
2.1.2.2直接获得调平树的手动计算方法

调整原则:
(1)降低高度:
(2)保持二叉排序树的性质

获得插入后平衡结构的核心方法为:

  • 定根:中序遍历失衡子树,其中中间结点为调整后的根结点
  • 定左孩子:为失衡子树中序遍历后中间结点前驱
  • 定右孩子:为失衡子树中序遍历后中间结点后继

同样以上述四种基本类型进行实例分析:
在这里插入图片描述

2.1.2.3调整平衡的一般方法
2.1.2.3.1根据失衡结点与其左右孩子结点的平衡因子来判断失衡类型

在这里插入图片描述
分析如下:

  • ①失衡结点平衡因子等于2:证明左子树高于右子树,故为L ?

  • [1]左孩子平衡因子为1:证明左孩子的左子树高于右子树,故为LL

  • [2]左孩子平衡因子为-1:证明左孩子的左子树低于右子树,故为LR


  • ②失衡结点平衡因子等于-2:证明左子树低于右子树,故为R ?

  • [1]左孩子平衡因子为1:证明左孩子的左子树高于右子树,故为RL

  • [2]右孩子平衡因子为-1:证明右孩子的左子树低于右子树,故为RR

2.1.2.4左旋转:操作对象为RR型

核心操作:冲突的左孩变为右孩

实例1(直接旋转的实例):
在这里插入图片描述
在这里插入图片描述
调平好的平衡二叉树与原失衡的平衡二叉树中序遍历序列等价
在这里插入图片描述

实例2:(冲突的左孩子变为右孩子)
若旋转的失衡结点同时有左右孩子
则在左旋转的过程中,由之前的定根方法,
我们发现:新的根结点(失衡结点的右孩子)的左孩子与旋转结点的左孩子发生了冲突,
此时应该将新的根结点的左孩子作为
旋转后的失衡结点的右孩子
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
调平好的平衡二叉树与原失衡的平衡二叉树中序遍历序列等价
在这里插入图片描述

2.1.2.5右旋转:操作对象为LL型

核心操作:冲突的右孩变为左孩

实例1(直接旋转的实例):

在这里插入图片描述
在这里插入图片描述
调平好的平衡二叉树与原失衡的平衡二叉树中序遍历序列等价
在这里插入图片描述
实例2:(冲突的右孩子变为左孩子)与左旋十分类似
则在右旋转的过程中,由之前的定根方法,
我们发现:新的根结点(失衡结点的左孩子)的右孩子与旋转结点的右孩子发生了冲突,
此时应该将新的根结点的右孩子作为
旋转后的失衡结点的左孩子
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
调平好的平衡二叉树与原失衡的平衡二叉树中序遍历序列等价
在这里插入图片描述

小结:
在这里插入图片描述

2.1.2.6左旋左孩子,然后右旋:操作对象为LR型

(插入结点在失衡结点的左孩子的右子树上)

实例1:左旋孩子时(注意冲突的左孩变右孩),右旋失衡结点时(注意冲突的右孩变左孩)

【1】左旋左孩子
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
【2】右旋失衡结点:
在这里插入图片描述
在这里插入图片描述

2.1.2.7右旋右孩子,然后左旋:操作对象为RL型

(插入结点在失衡结点的右孩子的左子树上)

实例1:右旋孩子时(注意冲突的右孩变左孩),左旋失衡结点时(注意冲突的左孩变右孩)

【1】右旋孩子结点
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
【2】左旋失衡结点:
在这里插入图片描述
在这里插入图片描述

2.1.2.8二叉平衡树的插入注意事项:

在这里插入图片描述
实例如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.1.2.9二叉平衡树的删除结点注意事项:

删除结点后,可能不止会调整一次失衡,故需要依次沿着祖先,依次向上检查调整
在这里插入图片描述

1本程序在vc++6.0编译通过并能正常运行。 2主界面 程序已经尽量做到操作简便了,用户只需要根据提示一步步进行操作就行了。 六思考和总结: 这个课程设计的各个基本操作大部分都在我的综合性实验中实现了,所以做这个主要攻克插入和删除这两个算法!其中插入在书本上已经有了,其中的右平衡算法虽然没有给出,但通过给出的左平衡算法很容易就可以写出右平衡算法。所以最终的点就在于删除算法的实现!做的过程中对插入算法进行了非常非常多次的尝试!花了非常多的时间,这其中很多时候是在对程序进行单步调试,运用了VC6。0的众多良好工具,也学到了很多它的许多好的调试手段。 其中删除算法中最难想到的一点是:在用叶子结点代替要删除的非叶子结点后,应该递归的运用删除算法去删除叶子结点!这就是整个算法的核心,其中很强烈得体会到的递归的强大,递归的最高境界(我暂时能看到的境界)! 其它的都没什么了。选做的那两个算法很容易实现的: 1合并两棵平衡二叉排序树:只需遍历其中的一棵,将它的每一个元素插入到另一棵即可。 2拆分两棵平衡二叉排序树:只需以根结点为中心,左子树独立为一棵,右子树独立为一棵,最后将根插入到左子树或右子树即可。 BSTreeEmpty(BSTree T) 初始条件:平衡二叉排序树存在。 操作结果:若T为空平衡二叉排序树,则返回TRUE,否则FALSE. BSTreeDepth(BSTree T) 初始条件:平衡二叉排序树存在。 操作结果:返回T的深度。 LeafNum(BSTree T) 求叶子结点数,非递归中序遍历 NodeNum(BSTree T) 求结点数,非递归中序遍历 DestoryBSTree(BSTree *T) 后序遍历销毁平衡二叉排序树T R_Rotate(BSTree *p) 对以*p为根的平衡二叉排序树作右旋处理处理之后p指向新的树根结点 即旋转处理之前的左子树的根结点 L_Rotate(BSTree *p) 对以*p为根的平衡二叉排序树作左旋处理处理之后p指向新的树根结点, 即旋转处理之前的右子树的根结点 LeftBalance(BSTree *T) 对以指针T所指结点为根的平衡二叉排序树作左平衡旋转处理, 本算法结束时,指针T指向新的根结点 RightBalance(BSTree *T) 对以指针T所指结点为根的平衡二叉排序树作右平衡旋转处理, 本算法结束时,指针T指向新的根结点 Insert_AVL(BSTree *T, TElemType e, int *taller) 若在平衡的二叉排序树T中不存在和e有相同的关键字的结点, 则插入一个数据元素为e的新结点,并返回OK,否则返回ERROR. 若因插入而使二叉排序树失去平衡,则作平衡旋转处理 布尔变量taller反映T长高与否 InOrderTraverse(BSTree T) 递归中序遍历输出平衡二叉排序树 SearchBST(BSTree T, TElemType e, BSTree *f, BSTree *p) 在根指针T所指的平衡二叉排序树中递归的查找其元素值等于e的数据元素, 若查找成功,则指针p指向该数据元素结点,并返回TRUE,否则指针p 指向查找路径上访问的最后一个结点并返回FALSE,指针f指向T的双亲, 其初始调用值为NULL Delete_AVL(BSTree *T, TElemType e, int *shorter) 在平衡二叉排序树中删除元素值为e的结点,成功返回OK,失败返回ERROR PrintBSTree_GList(BSTree T) 以广义表形式打印出来 PrintBSTree_AoList(BSTree T, int length) 以凹入表形式打印,length初始值为0 Combine_Two_AVL(BSTree *T1, BSTree T2) 合并两棵平衡二叉排序树 Split_AVL(BSTree T, BSTree *T1, BSTree *T2) 拆分两棵平衡二叉树 } (2)存储结构的定义: typedef struct BSTNode { TElemType data; int bf; //结点的平衡因子 struct BSTNode *lchild, *rchild;//左.右孩子指针 }BSTNode, *BSTree;
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值