平衡二叉树(AVL)树
2016-07-02 22:10
204 查看
1、平衡二叉树定义
是一种二叉排序树(二叉查找树、二叉搜索树),其中每个节点的左子树和右子树的高度差不大于1。(左右子树也是平衡二叉树)
平衡因子BF = 二叉树节点的左子树深度减去右子树深度 = 节点的平衡因子(BF)
最小不平衡子树:距离插入节点最近的,且平衡因子的绝对值大于1的节点为根的子树。
为了提高查找效率,把二叉排序树构造成平衡二叉树。平衡二叉树的查找、插入和删除的时间复杂度都是O(logn),最坏情况下,二叉排序树的查找时间复杂度是O(n)即非常不平衡的斜树。所以要构造平衡二叉树提高查找效率。
2、平衡二叉树的构建方法:
若向平衡二叉树中插入一个新结点后破坏了平衡二叉树的平衡性。首先要找出插入新结点后失去平衡的最小子树根结点的指针。然后再调整这个子树中有关结点之间的链接关系,使之成为新的平衡子树。当失去平衡的最小子树被调整为平衡子树后,原有其他所有不平衡子树无需调整,整个二叉排序树就又成为一棵平衡二叉树。
失去平衡的最小子树是指以离插入结点最近,且平衡因子绝对值大于 1 的结点作为根的子树。假设用 A 表示失去平衡的最小子树的根结点,则调整该子树的操作可归纳为下列四种情况。
( 1 ) RR 型平衡旋转法(右旋)
由于在 A 的左孩子 B 的左子树上插入结点 F ,使 A 的平衡因子由 1 增至 2 而失去平衡。故需进行一次顺时针旋转操作。 即将 A 的左孩子 B 向右上旋转代替 A 作为根结点, A 向右下旋转成为 B 的右子树的根结点。而原来 B 的右子树则变成 A 的左子树。
( 2 ) LL 型平衡旋转法(左旋)
由于在 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 的节点。
是一种二叉排序树(二叉查找树、二叉搜索树),其中每个节点的左子树和右子树的高度差不大于1。(左右子树也是平衡二叉树)
平衡因子BF = 二叉树节点的左子树深度减去右子树深度 = 节点的平衡因子(BF)
最小不平衡子树:距离插入节点最近的,且平衡因子的绝对值大于1的节点为根的子树。
为了提高查找效率,把二叉排序树构造成平衡二叉树。平衡二叉树的查找、插入和删除的时间复杂度都是O(logn),最坏情况下,二叉排序树的查找时间复杂度是O(n)即非常不平衡的斜树。所以要构造平衡二叉树提高查找效率。
2、平衡二叉树的构建方法:
若向平衡二叉树中插入一个新结点后破坏了平衡二叉树的平衡性。首先要找出插入新结点后失去平衡的最小子树根结点的指针。然后再调整这个子树中有关结点之间的链接关系,使之成为新的平衡子树。当失去平衡的最小子树被调整为平衡子树后,原有其他所有不平衡子树无需调整,整个二叉排序树就又成为一棵平衡二叉树。
失去平衡的最小子树是指以离插入结点最近,且平衡因子绝对值大于 1 的结点作为根的子树。假设用 A 表示失去平衡的最小子树的根结点,则调整该子树的操作可归纳为下列四种情况。
( 1 ) RR 型平衡旋转法(右旋)
由于在 A 的左孩子 B 的左子树上插入结点 F ,使 A 的平衡因子由 1 增至 2 而失去平衡。故需进行一次顺时针旋转操作。 即将 A 的左孩子 B 向右上旋转代替 A 作为根结点, A 向右下旋转成为 B 的右子树的根结点。而原来 B 的右子树则变成 A 的左子树。
( 2 ) LL 型平衡旋转法(左旋)
由于在 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 的节点。
相关文章推荐
- Zookeeper实战之单机模式
- 学习VMware虚拟化技术
- HDU2021 发工资咯:)
- PHP购物车代码
- 结构体内字节对齐偏移量
- 算法导论 第15章 动态规划:15.1钢条切割
- Ubuntu下查看软件版本及安装位置
- PIXHAWK源码分析之二—Hello Sky(PIXHAWK读取姿态数据并且显示)
- [编程题] 有趣的数字
- 319. Bulb Switcher
- 那些年,我学过的公开课
- [HTTP] HTTP Verb
- centos7.0安装Apache+mysql+php
- QDUOJ - kkun的膜神帮
- 深入浅出Mybatis系列(十)---SQL执行流程分析(源码篇)
- 深入浅出Mybatis系列(九)---强大的动态SQL
- microstation level3 05 rotate acs
- Android新浪微博开发(二)界面设计之低版本实现Material Design效果
- PHP模板引擎(smarty)
- 深入浅出Mybatis系列(八)---mapper映射文件配置之select、resultMap