zoukankan      html  css  js  c++  java
  • AVL树

    1,AVL树又称平衡二叉树,它首先是一颗二叉查找树,但在二叉查找树中,某个结点的左右子树高度之差的绝对值可能会超过1,称之为不平衡。
         而在平衡二叉树中,任何结点的左右子树高度之差的绝对值会小于等于 1。
    2,为什么需要AVL树呢?在二叉查找树中最坏情况下查找某个元素的时间复杂度为O(n),而AVL树能保证查找操作的时间复杂度总为O(logn)。。
    3.avl树通过单旋转或者双旋转来实现保证树的平衡
    avl树和伸展树有很多相似之处,可以查看:伸展树的特点;
     

    AVL树

    AVL树是根据它的发明者G. M. Adelson-Velskii和E. M. Landis命名的。它是一种特殊的二叉搜索树AVL树要求: 任一节点的左子树深度和右子树深度相差不超过1

    (空树的深度为0。注意,有的教材中,采用了不同的深度定义方法,所以空树的深度为-1)

    下面是AVL树:

    AVL树

    AVL树的特性让二叉搜索树的节点实现平衡(balance):节点相对均匀分布,而不是偏向某一侧。因此,AVL树的搜索算法复杂度是log(n)的量级。

    我们在二叉搜索树中定义的操作,除了插入,都可以用在AVL树上 (假设使用懒惰删除)。如果进行插入操作,有可能会破坏AVL树的性质,比如:

    插入2: 破坏AVL树

    观察节点5,它的左子树深度为2,右子树深度为0,所以左右两个子树深度相差为2,不再是AVL树。由于2的加入,从节点6,1,5,3到2的层数都增加1。6, 1, 5节点的AVL性质都被破坏。如果从节点2向上回溯,节点5是第一个被破坏的。从节点3开始的子树深度加1,这是造成6, 1, 5的AVL性质被破坏的本质原因。我们将5和3之间的路径画成虚线(就好像挂了重物,边被拉断一样)。

    我们可以通过单旋转(single rotation),调整以5为根节点的子树,来修正因为插入一个元素而引起的对AVL性质的破坏。如下:

    Single rotation: 左侧超重,向右转

    通过单旋转,3成为新的根节点,2,5称为3的左右子节点。子树重新成为AVL树。该子树的深度减小1,这将自动修正2带给节点6,1的“超负荷”。

    单旋转效果如下:

     向右单旋转

    特别要注意的是,为了保持二叉树的性质,子树B过继给了节点5。

    向左单旋转与之类似。作为练习,可以尝试绘制向左单旋转的示意图。

    但如果插入的节点不是2,而是4,会是如何呢?

    插入4

    尝试单旋转,会发现无法解决问题。以5为根节点的子树向右单旋转后,树将以3为根节点,4,5为子节点。4比3大,却是3的左子节点,显然,这依然不符合二叉搜索树的性质。但基于和上面相似的原则(调整以5为根节点的树),我们发现有一个简单的解决方式:

    double rotation

    上面的操作被称作双旋转(double rotation)。双旋转实际上是进行两次单旋转: 4为根节点的子树先进行一次向左的单旋转,然后将5为根节点的子树进行了一次向右的单旋转。这样恢复了树的ACL性质。

    对于AVL树,可以证明,在新增一个节点时,总可以通过一次旋转恢复AVL树的性质。

    当我们插入一个新的节点时,在哪里旋转?是用单旋转还是双旋转?

    我们按照如下基本步骤进行:

    1. 按照二叉搜索树的方式增加节点,新增节点称为一个叶节点。

    2. 从新增节点开始,回溯到第一个失衡节点(5)。

        (如果回溯到根节点,还没有失衡节点,就说明该树已经符合AVL性质。)

    3. 找到断的边(5->3),并确定断弦的方向(5的左侧)

    4. 以断边下端(3)为根节点,确定两个子树中的哪一个深度大(左子树还是右子树)。

        (这两棵子树的深度不可能相等,而且深度大的子树包含有新增节点。想想为什么)

    5. 如果第2和第3步中的方向一致(都为左或者都为右),需要单旋转以失衡节点为根节点的子树。

        否则,双旋转以失衡节点为根节点的子树。
  • 相关阅读:
    POJ 3923 Ugly Windows(——考察思维缜密性的模拟题)
    POJ 3829 Seat taking up is tough(——只是题目很长的模拟)
    练习json读取中文
    关于调接口和腾讯云cos方面。
    JavaScript如何处理解析JSON数据详解
    js获取url参数值的两种方式
    修改Host,配置域名访问
    Atom设置震撼的编辑效果
    atom总结
    用node.js可以开启静态服务 不需要借助apache 或者xampl
  • 原文地址:https://www.cnblogs.com/anzhi/p/7447750.html
Copyright © 2011-2022 走看看