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;
}