码迷,mamicode.com
首页 > 其他好文 > 详细

个人项目:数据结构之AVL树的实现

时间:2015-04-27 20:06:18      阅读:135      评论:0      收藏:0      [点我收藏+]

标签:

AVL树为了防止树的深度过深出现的一种数据结构,在二叉树的基础上添加了一条规则:每个节点的左子数与右子树的高度最多差1。

其中的难点之一为:插入一个节点。删除一个节点更难,在这里采用懒惰删除法。其中,在插入的时候更新根节点路径上那些节点的所有高度。

AVL节点:

struct AvlNode
{
    ElementType Element;
    AvlTree Left;
    AvlTree Right;
    int Height;
};
//问题一:当插入一个节点时,如何知道哪个节点失去平衡

在插入一个节点的时候,可以通过对树进行简单的修正来使新的树满足AVL树的特性----旋转。

把需要平衡的节点叫做a。由于任意节点最多有两个节点,因此高度不平衡时,a点的两棵子树的高度差2。可以猜想出,这种不平衡可能出现在下列四种情况中:

  1. 对a的左儿子的左子树进行一次插入
  2. 对a的左儿子的右子树进行一次插入
  3. 对a的右儿子的右子树进行一次插入
  4. 对a的右儿子的左子树进行一次插入

其中情形1和3,2和4是关于a点镜像对称,具体巧妙可在代码中看出。其中调整1和3的情况是进行一次单旋转,2和4则需要一次双旋转。

1.对a的左儿子的左子树进行一次插入时,出现不平衡的情形为:

技术分享

旋转代码为:

static Position SingleRotateWithLeft(Position K2)
{
    Position K1;

    K1 = K2->Left;
    K2->Left = K1->Right;
    K1->Right = K2;

    K2->Height = Max(Height(K2->Left), Height(K2->Right)) + 1;
    K1->Height = Max(K2->Height, Height(K1->Right)) + 1;

    return K1;
}

2.对a的左儿子的右子树插入一个节点,出现不平衡的情形为:
技术分享

旋转代码为:

static Position DoubleRotateWithLeft(Position K3)
{
    K3->Left = SingleRotateWithRight(K3->Left);

    return SingleRotateWithLeft(K3);
}

3和4的旋转代码为:

static Position SingleRotateWithRight(Position K2)
{
    Position K1;

    K1 = K2->Right;
    K2->Right = K1->Left;
    K1->Left = K2;

    K2->Height = Max(Height(K2->Left), Height(K2->Right)) + 1;
    K1->Height = Max(K2->Height, Height(K1->Right)) + 1;

    return K1;
}
static Position DoubleRotateWithRight(Position K3)
{
    K3->Right = SingleRotateWithLeft(K3->Right);

    return SingleRotateWithRight(K3);
}

 

个人项目:数据结构之AVL树的实现

标签:

原文地址:http://www.cnblogs.com/dd550023981/p/4458603.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!