• 平衡二叉树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,则需要进行一次单向左的旋转处理,并且在左旋之后,更新根节点和其左,右子树根节点的平衡因子,树的深度不变;
  • 相关阅读:
    开发常见错误之 :Missing artifact com.sun:tools:jar 1.7.0
    开发常见错误之 : Detected both log4j-over-slf4j.jar AND slf4j-log4j12.jar
    kafka集群部署
    kafka
    Oracle 学习之触发器
    CloudSetuper
    erlang :打开界面工具的命令
    erlang 二进制中 拼接 变量或者函数 报错
    Python内部机制。
    AOP (面向切面编程)
  • 原文地址:https://www.cnblogs.com/pacino12134/p/11068954.html
Copyright © 2020-2023  润新知