AVL树

动态平衡技术
Adelson-Velskii 和 Landis 提出了一个动态地保持二叉排序树平衡的方法,其基本思想是:
  在构造二叉排序树的过程中,每当插入一个结点时,首先检查是否因插入而破坏了树的平衡性,如果是因插入结点而破坏了树的平衡性,则找出其中最小不平衡子树,在保持排序树特性的前提下,调整最小不平衡子树中各结点之间的连接关系,以达到新的平衡。通常将这样得到的平衡二叉排序树简称为 AVL 树
那么什么是 最小不平衡子树
  以离插入结点最近、且平衡因子绝对值大于 1 的结点作根结点的子树。为了简化讨论,不妨假设二叉排序树的最小不平衡子树的根结点为 A ,则调整该子树的规律可归纳为下列四种情况:
如图:当插入结点为53时,结点37则为最小不平衡子树 A
单向
(1) LL 型:(单向右旋)
原因是:在A的左子树插入左子树,导致A平衡恩子为2,失去平衡。需要向右旋转一次、

  新结点 X 插在 A 的左孩子的左子树里。调整方法见图 8.5(a) 。图中以 B 为轴心,将 A 结点从 B 的右上方转到 B 的右下侧,使 A 成为 B 的右孩子。


(2)RR 型:(单向向左旋)
同上。则是方向变了右
  新结点 X 插在 A 的右孩子的右子树里。调整方法见图 8.5(b) 。图中以 B 为轴心,将 A 结点从 B 的左上方转到 B 的左下侧,使 A 成为 B 的左孩子。



双向:
(3)LR 型:(先左后右)
  新结点 X 插在 A 的左孩子的右子树里。调整方法见图 8.5(c) 。分为两步进行:第一步以 X 为轴心,将 B 从 X 的左上方转到 X 的左下侧,使 B 成为 X 的左孩子, X 成为 A 的左孩子。第二步跟 LL 型一样处理 ( 应以 X 为轴心 ) 。 
//此时大小是 B<X<A 那么应该将中间的那个X做根结点
(4)RL 型:(先右后左)
  新结点 X 插在 A 的右孩子的左子树里。调整方法见图 8.5(d) 。分为两步进行:第一步以 X 为轴心,将 B 从 X 的右上方转到 X 的右下侧,使 B 成为 X 的右孩子, X 成为 A 的右孩子。第二步跟 RR 型一样处理 ( 应以 X 为轴心


#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef int ELementType;

struct AvlNode;
typedef struct AvlNode *Position;
typedef struct AvlNode *AvlTree;


AvlTree MakeEmpty(AvlTree T);
Position Find(ELementType X, AvlTree T);
Position FindMin(AvlTree T);
Position FindMax(AvlTree T);

AvlTree Insert(ELementType X, AvlTree T);
AvlTree Delete(ELementType X, AvlTree T);

ELementType Retrieve(Position P);
static int  height(Position P);
//旋转
static Position SingleRotateWithRight(Position K1);
static Position SingleRotateWithLeft(Position K2);
static Position DoubleRotateWithLeft(Position K3);
static Position DoubleRotateWithRight(Position K4);

ELementType Max( ELementType a, ELementType b);

void PrintElement(AvlTree T);
void PreOrder(AvlTree T);
void InOrder(AvlTree T);
void PostOrder(AvlTree T);



struct AvlNode
{
        ELementType ELement;
        AvlTree Left;
        AvlTree Right;
        int height;  //节点对应高度
};


ELementType 
Max(ELementType a, ELementType b)
{
        return (a > b ? a : b);    
}

static int
height(Position P) 
{
   if( P == NULL)
           return -1;
   else
           return P->height;
}

AvlTree
MakeEmpty( AvlTree T)
{
        if( T != NULL)
        {
                MakeEmpty(T->Left);
                MakeEmpty(T->Right);
                free(T);
        }
        return NULL;
}

Position 
Find(ELementType X, AvlTree T)
{
        if( T == NULL)
                return NULL;
        
        if( X < T->ELement)
                return Find(X,T->Left );
        else if( X > T->ELement)
                return Find(X,T->Right);
        else
                return T;
}


Position
FindMin(AvlTree T)
{
        if( T == NULL)
                return NULL;
        
        if( T->Left == NULL)
                return T;
        else
                return FindMin(T->Left);
}

Position 
FindMax(AvlTree T)
{
        if(T == NULL)
                return NULL;
        else
                if(T->Right == NULL)
                        return T;
                else
                        return FindMax(T->Right);
}



AvlTree
Delete(ELementType X, AvlTree T)
{
        return T;
}


AvlTree 
Insert( ELementType X, AvlTree T)
{

        if( T ==  NULL)
        {
                T = malloc(sizeof(struct AvlNode));
                if( T == NULL)
                        printf("ERROR 129\n");
                else                
                {
                        T->ELement = X;
                        T->Left = T->Right = NULL;
                }
        }
        else if(X < T->ELement)
        {
                T->Left = Insert(X ,T->Left);
                if( height( T->Left) - height(T->Right) == 2)
                {
                        if( X < T->Left->ELement)
                        {
                                T = SingleRotateWithLeft(T);
                        }
                        else
                        {
                                T = DoubleRotateWithLeft(T);
                        }
                }
        }
        else if( X >T->ELement)
        {
                T->Right = Insert(X,T->Right);
                if( height(T->Right) - height(T->Left) == 2)
                {
                        if( X > T->Right->ELement)
                        {
                                T =SingleRotateWithRight(T);
                        }
                        else
                        {
                                T =DoubleRotateWithRight(T);
                        }
                }
        }
        T->height = Max(height(T->Left),height(T->Right)) +1; 
        return T;
}


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(height(K1->Left),height(K1->Right)) + 1;

        return K1;
}


static Position
SingleRotateWithRight(Position K1)
{
        Position K2;
        K2 = K1->Right;
        K1->Right = K2->Left;
        K2->Left = K1;

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

        return K2;
}

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

static Position
DoubleRotateWithRight(Position K4)
{
        K4->Right = SingleRotateWithLeft(K4->Right);
        return SingleRotateWithRight(K4);
}


ELementType 
Retrieve(Position P)
{
        return P->ELement;
}


void
PrintElement(AvlTree T)
{
        printf("%3d ",Retrieve( T ));
}

void
PreOrder( AvlTree T)
{
        if( T != NULL)
        {
                PrintElement( T);
                PreOrder( T->Left);
                PreOrder( T->Right);
        }
}



void
InOrder( AvlTree T)
{
        if( T != NULL)
        {
                InOrder( T->Left);
                PrintElement( T);
                InOrder( T->Right);
        }
}


void
PostOrder(AvlTree T )
{
        if( T != NULL)
        {
                PostOrder( T);
                PostOrder(T);
                PrintElement(T);
        }
}




int main()  
{  
        AvlTree T = NULL;  
        int i, n;  
        int  tmp;  
        printf( "Number of Elements:" );  
        scanf( "%d", &n );  
        for ( i = 0; i < n; i++)  
        {  
                scanf( "%d", &tmp );  
                T = Insert( tmp, T );  
        }  
        printf( "\nPreOrder :" );  
        PreOrder( T );  
        printf( "\nInOrder  :" );  
        InOrder( T );  
        printf( "\nPostOrder:" );  
        PostOrder( T );  
        printf( "\n" );  
        return 0;  
}  










                         
 
                 

 


posted @ 2012-09-15 11:12  风去无痕  阅读(189)  评论(0编辑  收藏  举报