(堆6-1)AVL Insertion--C语言

You are supposed to implement the Insert function, which inserts an integer Key into an AVL tree T. The resulting tree must be returned.

函数接口定义:

AVLTree Insert ( AVLTree T, int Key );

where AVLTree is defined as the following:

typedef struct AVLNode *PtrToAVLNode;
struct AVLNode{
int Key;
PtrToAVLNode Left;
PtrToAVLNode Right;
int Height;
};
typedef PtrToAVLNode AVLTree;

裁判测试程序样例:

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

typedef struct AVLNode *PtrToAVLNode;
struct AVLNode{
    int Key;
    PtrToAVLNode Left;
    PtrToAVLNode Right;
    int Height;
};
typedef PtrToAVLNode AVLTree;

AVLTree Insert ( AVLTree T, int Key );
void PostOrderPrint( AVLTree T ); /* details omitted */
void InOrderPrint( AVLTree T );   /* details omitted */

int main()
{
    int N, Key, i;
    AVLTree T = NULL;

    scanf("%d", &N);
    for ( i=0; i<N; i++ ) {
        scanf("%d", &Key);
        T = Insert( T, Key );
    }
    PostOrderPrint( T );
    InOrderPrint( T );

    return 0;
}
/* Your function will be put here */

输入样例:

7
88 70 61 96 120 90 65

输出样例:

Post-order: 61 70 65 90 120 96 88
In-order: 61 65 70 88 90 96 120

代码:

int GetHeight(AVLTree T)
{
    if(T==NULL)
        return 0;
    else
    {
        return T->Height;
    }
}
int Max(int a,int b)
{
    if(a>=b) return a;
    else return b;
}
/*伪代码
AVLTree LeftRotation(AVLTree A)
{
    /*
    左旋,就是将根结点A挪到A的左孩子B的右子树上
    1.先用一个变量B指向A的左孩子,用于记录左孩子的位置
    2.A的左孩子指向B的右孩子,把B的右孩子挪到A的左子树上
    3.B是A的左子树中的一部分,因此B上的任何结点都小于A,把B的右孩子挪到A的左子树上符合平衡
    4.此时B的右子树为空,可以将A挪到B的右子树上
    
   AVLTree B=A->Left;
   A->Left=B->Right;
   B->Right=A;
   //高度调整,因为每个结点都有高度,因此调整过的结点都需要重新更新高度
   A->Height=Max(A左子树树高,A右子树树高)+1;
   B->Height=Max(B左子树树高,B右子树树高)+1;
   return B;//此时B已经作为根结点代替原来的A
}
*/
AVLTree LeftRotation(AVLTree A)
{
    AVLTree B=A->Left;
    A->Left=B->Right;
    B->Right=A;
    A->Height=Max(GetHeight(A->Left),GetHeight(A->Right))+1;
    B->Height=Max(GetHeight(B->Right),GetHeight(B->Right))+1;
    return B;
}
AVLTree RightRotation(AVLTree A)
{
    AVLTree B=A->Right;
    A->Right=B->Left;
    B->Left=A;
    A->Height=Max(GetHeight(A->Left),GetHeight(A->Right))+1;
    B->Height=Max(GetHeight(B->Right),A->Height)+1;
    return B;
}
AVLTree RightLeftRotation(AVLTree A)//右左旋:A的右子树先左旋后A右旋
{
    A->Right=LeftRotation(A->Right);
    return RightRotation(A);
}
AVLTree LeftRightRotation(AVLTree A)//左右旋:A的左子树先右旋后A左旋
{
    A->Left=RightRotation(A->Left);
    return LeftRotation(A);
}
/*伪代码
AVLTree Insert ( AVLTree T, int Key )
{
    if(T为空)
    {
        插入新结点
    }
    else if(T->Key<Key)//插入右子树
    {
        //先调用递归把新结点插入树中
        T->Right=Insert(T->Right,Key);
        //判断是否需要右旋,右旋条件:左子树树高-右子树树高=-2
        if(左子树树高-右子树树高=-2)
        {
            if(插入的新结点的Key比右结点的Key大)
                右旋
            else
                右左旋
        }
    }
    else if(T->Key>Key)//插入左子树
    {
        //先调用递归把新结点插入树中
        T->Left=Insert(T->Left,Key);
        //判断是否需要左旋,左旋条件:左子树树高-右子树树高=2
        if(左子树树高-右子树树高=2)
        {
            if(插入的新结点的Key比左结点的Key小)
                左旋
            else
                左右旋
        }
    }
    //因为经过旋转后树高发生改变,记录树高的T->Height要重新赋值
    T->Height=Max(左子树树高,右子树树高)+1;
    return T;
}
*/
AVLTree Insert ( AVLTree T, int Key )
{
    if(!T)//插入空树
    {
        T=(AVLTree)malloc(sizeof(struct AVLNode));
        T->Key=Key;
        T->Height=1;
        T->Left=T->Right=NULL;
    }
    else if(Key>T->Key)//插入右子树
    {
        T->Right=Insert(T->Right,Key);//调用递归,直到把Key插入树中
        //如果需要右旋(条件:左子树树高-右子树树高=-2)
        if(GetHeight(T->Left)-GetHeight(T->Right)==-2)
        {
            if(Key>T->Right->Key)//插入的新结点的Key比右结点的Key大
                T=RightRotation(T);//右旋
            else
                T=RightLeftRotation(T);//右左旋
        }
    }
    else if(Key<T->Key)//插入左子树
    {
        T->Left=Insert(T->Left,Key);
        if(GetHeight(T->Left)-GetHeight(T->Right)==2)
        {
            if(Key<T->Left->Key)//插入的新结点的Key比左结点的Key小
            {
                T=LeftRotation(T);//左旋
            }
            else
            {
                T=LeftRightRotation(T);//左右旋
            }
        }
    }
    T->Height=Max(GetHeight(T->Left),GetHeight(T->Right))+1;
    return T;
}
  • 10
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值