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

    可以是空树。

    性质:

    任何父节点的左右子树深度差<=1;

    BF平衡因子=左子树深度-右子树深度,则所有节点平衡因子-1,0,1;

    有些BST初始序列或者插入后对BST的影响,导致可能出现下面这种情况,将导致我们的二叉排序树的效率大大降低:

    为了避免这种情况的发生,我们希望可以有一种算法,将我们的不平衡的二叉排序树转化为平衡二叉排序树。这样就可以让我们的二叉排序树结构最优化。

    上图中a是,b不是。

    为什么需要平衡二叉树?

    平衡二叉树上的任何一个结点左右字数的深度之差都不会超过1,则可以证明它的深度和logn是同数量级的,所以其平均查找长度也和logn同数量级。

    但是事于愿违有些二叉排序树的插入,或者初始序列由于其插入的先后顺序等缘故,将导致我们的二叉排序树的效率大大降低。如下图 :

    为了避免这种情况的发生,我们希望可以有一种算法,将我们的不平衡的二叉排序树转化为平衡二叉排序树。这样就可以让我们的二叉排序树结构最优化。

    a是AVL;

    b也是;

    c也是;

    d不是,平衡因子出现了-2,将-2逆时针旋转(单向左旋平衡处理)得到e;

    e是;

    f不是,先将53顺时针旋转变成g,再将53逆时针旋转得到h;(双向旋转(先右后左)平衡处理

    如何证明我们插入的正确性:中序遍历所得关键字的值序列从小到大即可(二叉排序树的性质)

    那么如何创建一颗平衡二叉树呢?

    创建平衡二叉树,我们采用依次插入节点e的方式进行。

    而平衡二叉树上插入节点采用递归的方式进行。

    1、若空树,将e作为根节点,高度+1;

    2、若要e==根节点,不插入;

    3、e<root && 左子树种≠e,插入到左子树中,深度+1;

    • 若root平衡因子-1,左浅右深,root左旋,root平衡因子变为0,BBST深度不变;
    • root平衡因子0,root平衡因子改为1,BST深度+1;
    • root平衡因子1,左深右浅。
      • 若左子节点平衡因子1,右旋,根节点和其右子树根节点的平衡因子更改为0,树的深度不变;
      • 若左子节点平衡因子-1,先左旋,后右旋,修改根节点和其左,右子树根节点的平衡因子,树的深度不变;

    4、e>root && 右子树中≠e,插入到右子树中,深度+1;

    • 若root平衡因子1,左深右浅,右旋,root改为0,深度不变;
    • 若root平衡因子0,将root改为-1,不用旋,树深度+1;
    • 若root平衡因子-1,左浅

    (4)若e的关键字大于BBST的根节点的关键字,而且在BBST的右子树中不存在和e有相同关键字的节点,则将e插入到BBST的右子树上,并且当插入之后的右子树深度加1时,分别就不同的情况处理之。

      • BBST的根节点的平衡因子是1(左子树的深度大于右子树的深度):则将根节点的平衡因子修改为0(右旋),BBST的深度不变;

      • BBST的根节点的平衡因子是0(左右子树的深度相等):则将根节点的平衡因子修改为-1(不用旋),树的深度加1;

      • BBST的根节点的平衡因子为-1(右子树的深度大于左子树的深度):若BBST的右子树根节点的平衡因子为1,则需要进行两次选择,第一次先向右旋转,再向左旋转处理,并且在旋转处理之后,修改根节点和其左,右子树根节点的平衡因子,树的深度不变; 
        若BBST的右子树根节点的平衡因子为1,则需要进行一次单向左的旋转处理,并且在左旋之后,更新根节点和其左,右子树根节点的平衡因子,树的深度不变;
  • 相关阅读:
    生成XML文件
    webService的发布与调用
    does not contain bitcode ShardSDK等三方库
    IOS在Document目录下创建文件夹、保存、读取、以及删除文件
    判断IOS安装后是否是第一次启动
    OC中使用单例模式
    两个时间(日期)段交集判断方法
    $(document).ready vs. $(window).load
    基于vant上传图片添加水印
    常用的正则校验
  • 原文地址:https://www.cnblogs.com/pacino12134/p/11068954.html
Copyright © 2011-2022 走看看