AVL树初学笔记

原创 2015年11月20日 21:24:08

AVL树是带有平衡条件的binary_search_tree,要求每个节点的左子树和右子树的高度相差不超过1
插入一个节点可能破会avl的平衡性,所以我们要在插入后对不满足条件的部分进行修正
总的来说需要修改的情形有这么几种:

1,连续两个节点朝一个方向倾斜–single ronate:
抱歉画反了
这种情况下我们使用一次单旋转:
找出三个元素中的中间值作为节点,其他两个当作树叶
就相当于把3和4进行一次”旋转“如下图:
旋转后
这样就将高度降低了1

2,两个节点倾斜的方向相反:
双旋转1
如此也是像上一个一样,找出中间值然后作为父节点:
由于形式不一样,我们需要旋转两次,先把14和7旋转,再把14和15旋转
我们称之为左右双旋转
旋转后

3,上面讨论的都是简单的情况,但是有时候我们要旋转的节点和其他节点又有联系:也就是说我们要处理节点的分支
下面举几个例子:
这里写图片描述
在这里我们首先要确定调整哪个节点:看哪个节点的左右子树高度差距大于1,得到2,此时我们把5,6节点看成是一个整体节点,我们要把2,4,5+6这三个节点进行调整,对应情况1,单旋转一次:
将4作为父节点->这种情况下4还有一个高度为1的矮一些的树,我们将其改为原先父节点的右子树,如上图

这里写图片描述
这里的情况和上图稍有不同的是要确定是调整6还是调整4,因为这两个树节点的左右子树均不符合
这种情况下我们选择调整小的(或从下往上调整)
所以我们调整6:
这里6的右子树和它需要一次双旋转,同样,我们将6,15,7进行处理
7成为父节点,7的右子树继续成为7的父节点的左子树原先的父节点成为新父节点的左子树

图片来自书
现在我们插入13,插入13引起新的不平衡,要调整的父节点为4,4的左子树(要调整的子树)父节点为7,由于13不在4和7之间,所以用但旋转就能解决问题。
(调整父节点,不平衡的子树父节点,以及根据单双旋转确定的要调整的节点)

不完整代码:
static int height(avlnode* t)
{
    if (t == NULL)
        return -1;
    else return t->height;
}
avlnode* singleRonateWithLeft(avlnode* t)
{
    avlnode* t1;
    t1 = t->left;
    t->left = t1->right;
    t1->right = t;

    t->height = max(height(t->left), height(t->right)) + 1;
    t1->height = max(height(t1->left), t->height) + 1;

    return t1;//new father node
}
avlnode* doubleRonateWithLeft(avlnode* t)
{
    t->left = singleRonateWithRight(t->left);

    return singleRonateWithLeft(t);
}
avlnode* singleRonateWithRight(avlnode* t)
{
    avlnode* t1 = t->right;
    t->right = t1->left;
    t1->left = t;

    t->height = max(height(t->left), height(t->right)) + 1;
    t1->height = max(height(t1->right), t->height) + 1;

    return t1;
}
avlnode* doubleRonateWithRight(avlnode* t)
{
    singleRonateWithLeft(t->right);

    return singleRonateWithRight(t);
}


avlnode* insert(avlnode*t, elemtype x)
{
    if (t == NULL)
        //alloc 
        ;
    else if (x < t->data)
    {
        t->left = insert(t->left, x);
        //we check after "insert" is done
        if (height(t->left) - height(t->right) == 2)
        {
            if (x < t->left->data)//go all the way left,case 1
                t = singleRonateWithLeft(t);
            else
                t = doubleRonateWithLeft(t);
        }
    }
    else if (x > t->data)
    {
        t->right = insert(t->right, x);
        if (x>t->right->data)
            t = singleRonateWithRight(t);
        else t = doubleRonateWithRight(t);
    }

    t->height = max(height(t->left), height(t->right)) + 1;
    return t;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。

AVL树[非常详细有用]

定义:一棵空二叉树是AVL树,如果T是非空二叉树,TL和TR分别是其左子树和右子树, 则当且仅当TL和TR都为AVL树且|HL-HR| 由定义知道一个AVL树的任何节点的左右子树的高度之差不超过1...
  • fly_feidream
  • fly_feidream
  • 2013年05月01日 09:51
  • 1802

AVL树的初步生成与插入操作

平衡二叉树(Balanced Binary Tree)又被称为AVL树(有别于AVL算法),且具有以下性质:它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树...
  • u011446963
  • u011446963
  • 2015年07月02日 17:05
  • 1331

AVL树插入、删除的分析与实现

AVL树基本概念 首先,AVL树也是一种
  • u013941223
  • u013941223
  • 2014年07月10日 10:19
  • 1934

【C++研发面试笔记】10. 基本数据结构-平衡二叉搜索树AVL

【C++研发面试笔记】10. 基本数据结构-平衡二叉搜索树AVL10.1 AVL的定义定义:平衡二叉树或为空树,或为如下性质的二叉排序树: (1)左右子树深度之差的绝对值不超过1; (2)左右子树...
  • tostq
  • tostq
  • 2016年10月02日 21:52
  • 781

[算法学习笔记] AVL树----带有平衡条件的二叉搜索树

图片及部分内容来自博客http://www.cnblogs.com/skywang12345/p/3576969.html 这个博客写的很用心,大家可以看看这个 二叉搜索树关于二叉搜索树我之前的...
  • u014235934
  • u014235934
  • 2016年07月27日 18:49
  • 513

数据结构学习笔记:B树、B+树、红黑树、AVL树

B树、B+树、红黑树、AVL树
  • TQH_Candy
  • TQH_Candy
  • 2016年09月15日 19:27
  • 237

数据结构与算法分析学习笔记--第四章AVL树

#include using namespace std; template class AVL_Node { public: AVL_Node *m_left; AVL_Node *m_rig...
  • u012829687
  • u012829687
  • 2014年06月07日 16:40
  • 299

[学习笔记]AVL平衡二叉树

AVL平衡二叉树的实现
  • cyxvc
  • cyxvc
  • 2015年08月26日 14:00
  • 235

AVL树读书笔记

最近开始了自己高级数据结构之旅,在这次旅行中,我将持续把一些高级的数据结构从理论到编码都过一遍,同时通过博客形式分享出来,希望大家指出不足之处!      二叉排序树是一种动态排序的数据结构,支持插入...
  • xj2419174554
  • xj2419174554
  • 2014年04月27日 13:54
  • 1313

平衡二叉树AVL的笔记

二叉树 左子树都小于根节点,右子树都大于根节点。可以动态维护这棵树(因为是树结构,可以有限步完成插入),所以是动态查找算法。时间复杂度为O(logn)在46.5%的情况下,需要把二叉树平衡化成“...
  • kllihuang
  • kllihuang
  • 2011年08月19日 21:19
  • 825
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:AVL树初学笔记
举报原因:
原因补充:

(最多只允许输入30个字)