Root of AVL Tree
题目描述
An AVL tree is a self-balancing binary search tree. In an AVL tree, the heights of the two child subtrees of any node differ by at most one; if at any time they differ by more than one, rebalancing is done to restore this property. Figures 1-4 illustrate the rotation rules.
Now given a sequence of insertions, you are supposed to tell the root of the resulting AVL tree.
Input Specification:
Each input file contains one test case. For each case, the first line contains a positive integer N (≤20) which is the total number of keys to be inserted. Then N distinct integer keys are given in the next line. All the numbers in a line are separated by a space.
Output Specification:
For each test case, print the root of the resulting AVL tree in one line.
Sample Input 1:
5
88 70 61 96 120
Sample Output 1:
70
Sample Input 2:
7
88 70 61 96 120 90 65
Sample Output 2:
88
思路:
本题主要是学会平衡二叉树的几种旋转方法以及何时进行旋转。旋转过程的描述一定要画图,根据图来写代码,这样会简单很多。其次本题用到很多递归的思想,这是树结构中常用的算法,要深刻体会。
#include<cstdlib>
#include<stdio.h>
typedef struct Treenode* Tree;
Tree maketree(int n); //建树
Tree newnode(int data); //创建新节点
Tree Insert(Tree T, int data); //插入节点
int height(Tree T); //计算树的高度
Tree LLrotation(Tree T);
Tree LRrotation(Tree T);
Tree RRrotation(Tree T);
Tree RLrotation(Tree T);
//定义
struct Treenode{
int data;
Tree left;
Tree right;
};
//主程序
int main()
{
int n;
scanf("%d\n", &n);
Tree T = maketree(n); //是程序的主要部分,返回最后的根节点
printf("%d", T->data);
return 0;
}
Tree maketree(int n)
{
int v;
scanf("%d", &v);
Tree T = newnode(v); //根节点单独写出
for(int i = 1; i < n; i++)
{
scanf("%d", &v);
T = Insert(T, v);
}
return T;
}
Tree newnode(int data)
{
Tree T = (Tree)malloc(sizeof(struct Treenode));
T->data = data;
T->left = 0;
T->right = 0;
return T;
}
Tree Insert(Tree T, int data)
{
if(!T) {T = newnode(data);} //递归终止条件
else {
if(data < T->data){
T->left = Insert(T->left, data);
if(height(T->left) - height(T->right) == 2)
if(data < T->left->data) //新节点在左子树的左边
T = LLrotation(T);
else T = LRrotation(T); //新节点在左子树的右边
}
else{
T->right = Insert(T->right, data);
if(height(T->right) - height(T->left) == 2)
if(data > T->right->data) //新节点在右子树的右边
T = RRrotation(T);
else T = RLrotation(T); //新节点在右子树的左边
}
}
return T;
}
//求树的最大深度,其实一行代码可以解决
int height(Tree T)
{
int max, hl, hr;
if(T)
{
hl = height(T->left);
hr = height(T->right);
max = hl>hr?hl:hr;
return max + 1;
}
else return 1;
//一行代码版
//return T?1:(max(height(T->left), height(T->right))+1);
}
//下面开始写旋转的函数,最好是将图形画出来,很快就能写完
Tree LLrotation(Tree T)
{
Tree a = T, b = T->left; //交换的节点
Tree ar = a->right, bl = b->left, br = b->right; //附属节点
b->right = a;
b->left = bl;
a->left = br;
a->right = ar;
return b;
}
Tree LRrotation(Tree T)
{
Tree a = T, b = T->left, c = b->right;
Tree ar = a->right, bl = b->left, cl = c->left, cr = c->right;
c->left = b; c->right = a;
b->left = bl; b->right = cl;
a->left = cr; a->right = ar;
return c;
}
Tree RRrotation(Tree T)
{
Tree a = T, b = T->right;
Tree al = a->left, bl = b->left, br = b->right;
b->left = a; b->right = br;
a->left = al; a->right = bl;
return b;
}
Tree RLrotation(Tree T)
{
Tree a = T, b = T->right, c = b->left;
Tree al = a->left, br = b->right, cl = c->left, cr = c->right;
c->left = a; c->right = b;
a->left = al; a->right = cl;
b->left = cr; b->right = br;
return c;
}