zoukankan      html  css  js  c++  java
  • 平衡二叉树

    平衡二叉树(Balanced binary tree)是由阿德尔森-维尔斯和兰迪斯(Adelson-Velskii and Landis)于1962年首先提出的,所以又称为AVL树。

    定义:平衡二叉树或为空树,或为如下性质的二叉排序树:

    (1)左右子树深度之差的绝对值不超过1;

    (2)左右子树仍然为平衡二叉树.

         结点的平衡因子 = 左子树的高度 - 右子树的高度, 插入和删除操作都会导致AVL树的自我调整(自我平衡),使得所有结点的平衡因子保持为+1、-1或0。

         当子树的根结点的平衡因子为+1时,它是左倾斜的(left-heavy); 当子树的根结点的平衡因子为 -1时,它是右倾斜的(right-heavy)。

         一颗子树的根结点的平衡因子就代表该子树的平衡性。保持所有子树几乎都处于平衡状态,AVL树在总体上就能够基本保持平衡。

          平衡二叉树每个结点的平衡因子只能是1,0,-1。若其绝对值超过1,则该二叉排序树就是不平衡的。

       

    AVL树的基本查找、插入结点的操作和二叉树的操作一样。但是,当向AVL树中插入一个结点后,还有一些额外的工作要做。首先,必须计算因插入操作对平衡因子带来的改变。其次,如果任何平衡因子变成了+/-2,就必须从这个结点开始往下重新平衡这颗树,这个重新平衡的过程就称为旋转。

    AVL树的旋转

    旋转操作用来重新平衡树的某个部分。通过重新安排结点 ,使结点之间的关系始终保持左子结点小于父结点,父结点小于右子结点。使得该树仍然是一颗二叉搜索树。旋转过后,旋转子树中的所有结点的平衡因子都为+1、-1或0。

    AVL树的旋转类型有4种, 分别是LL(left-left)旋转、LR(left-right)旋转、RR(right-right)旋转和RL(right-left)旋转。

    为方便理解在何时执行哪一种旋转,设x代表刚插入AVL树中的结点,设A为离x最近且平衡因子更改为2的绝对值的祖先。可以归纳为下面4种处理情况:

    LL旋转

    如下图所示,当x位于A的左子树的左子树上时,执行LL旋转。设left为A的左子树,要执行LL旋转,将A的左指针指向left的右子结点,left的右指针指向A,将原来指向A的指针指向left。旋转过后,将A和left的平衡因子都改为0。所有其他结点的平衡因子没有发生变化。

    LR旋转

    当x位于A的左子树的右子树上时,执行LR旋转。设left是A的左子结点,并设A的子孙结点grandchild为left的右子结点。要执行LR旋转,将left的右子结点指向grandchild的左子结点,grandchild的左子结点指向left,A的左子结点指向grandchild的右子结点,再将grandchild的右子结点指向A,最后将原来指向A的指针指向grandchild。

    执行LR旋转之后,调整结点的平衡因子取决于旋转前grandchild结点的原平衡因子值。

    如果grandchild结点的原始平衡因子为+1,就将A的平衡因子设为-1,将left的平衡因子设为0。

    如果grandchild结点的原始平衡因子为0,就将A和left的平衡因子都设置为0。

    如果grandchild结点的原始平衡因子为-1,就将A的平衡因子设置为0,将left的平衡因子设置为+1。

    在所有的情况下,grandchild的新平衡因子都是0。所有其他结点的平衡因子都没有改变。

     

    RR旋转

    当x位于A的左子树的右子树上时,执行RR旋转。

    RR旋转与LL旋转是对称的关系。

    设A的右子结点为Right。要执行RR旋转,将A的右指针指向right的左子结点,right的左指针指向A,原来指向A的指针修改为指向right。

    完成旋转以后,将A和left的平衡因子都修改为0。所有其他结点的平衡因子都没有改变。

    RL旋转

    当x位于A的右子树的左子树上时,执行RL旋转。

     RL旋转与LR旋转是对称的关系。

    设A的右子结点为right,right的左子结点为grandchild。要执行RL旋转,将right结点的左子结点指向grandchild的右子结点,将grandchild的右子结点指向right,将A的右子结点指向grandchild的左子结点,将grandchild的左子结点指向A,最后将原来指向A的指针指向grandchild。

    执行RL旋转以后,调整结点的平衡因子取决于旋转前grandchild结点的原平衡因子。这里也有三种情况需要考虑:

    如果grandchild的原始平衡因子值为+1,将A的平衡因子更新为0,right的更新为-1;

    如果grandchild的原始平衡因子值为  0,将A和right的平衡因子都更新为0;

    如果grandchild的原始平衡因子值为-1,将A的平衡因子更新为+1,right的更新为0;

    在所有情况中,都将grandchild的新平衡因子设置为0。所有其他结点的平衡因子不发生改变。

  • 相关阅读:
    三个心态做人做学问 沧海
    成功走职场要找准自己的"快捷键" 沧海
    免费离线下载 拂晓风起
    Hibernate 获取某个表全部记录时 奇怪现象 (重复出现某个记录) 拂晓风起
    无法读取mdb 如果连接不了ACCESS mdb文件,就尝试安装MDAC 拂晓风起
    Netbeans 使用 Hibernate 逆向工程 生成hbm和pojo 拂晓风起
    如何点击单选框 radio 后面的文字,选中单选框 拂晓风起
    Java 连接access 使用access文件 不用配置 拂晓风起
    mysql下如何执行sql脚本 拂晓风起
    Hibernate配置access Hibernate 连接 access 拂晓风起
  • 原文地址:https://www.cnblogs.com/kaleidoscope/p/9492858.html
Copyright © 2011-2022 走看看