1066. Root of AVL Tree (25)
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 ythe 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
结题思路 :
题意要求我们输出平衡二叉树的根节点的值。
要求1:每棵子树的左右子树高度差不得超过1;
要求2:每次进行插值以后需要对表现高度差超过阈值的节点的子树进行高度调整;
要求3:在节点A的左子树的左子树进行插入引起的A的高度变化超过阈值,需要进行一次leftSingleRotation;
要求4:在节点A的右子树的右子树进行插入引起的A的高度变化超过阈值,需要进行一次rightSingleRotation;
要求5:在节点A的左子树的右子树进行插入引起的A的高度变化超过阈值,需要进行一次rightSingleRotation和leftSingleRotation;
要求6:在节点A的右子树的左子树进行插入引起的A的高度变化超过阈值,需要进行一次leftSingleRotation和rightSingleRotation;
图片转自:http://www.linuxidc.com/Linux/2014-12/110490.htm
程序步骤:
第一步、将每个读入的数据插入到平衡二叉树中; (此处未完成节点的删除)
第二步、输出平衡二叉树的根节点即可。
具体程序(AC)如下:
#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;
struct avlNode{
int value;
avlNode* left;
avlNode* right;
int height;
avlNode(int value,avlNode* l,avlNode* r,int height):value(value),left(l),right(r),height(height){}
};
int max(int a,int b)
{
return a>b?a:b;
}
int height(avlNode* root)
{
return (root==NULL)?-1:root->height;
}
void leftSingleRotation(avlNode* &root)//仅进行指针的移动↑
{
avlNode* resultRoot=root->left;
root->left=resultRoot->right;
resultRoot->right=root;
root->height=max(height(root->left),height(root->right))+1;
resultRoot->height=max(height(resultRoot->left),height(resultRoot->right))+1;
root=resultRoot;
}
void rightSingleRotation(avlNode* &root)//仅进行指针的移动↑
{
avlNode* resultRoot=root->right;
root->right=resultRoot->left;
resultRoot->left=root;
root->height=max(height(root->left),height(root->right))+1;
resultRoot->height=max(height(resultRoot->left),height(resultRoot->right))+1;
root=resultRoot;
}
void leftDoubleRotation(avlNode* &root)
{
rightSingleRotation(root->left);
leftSingleRotation(root);
}
void rightDoubleRotation(avlNode* &root)
{
leftSingleRotation(root->right);
rightSingleRotation(root);
}
void insert(int value,avlNode * &t)
{
if(!t)
t=new avlNode(value,NULL,NULL,0);
else if(value<t->value)
{
insert(value,t->left);
if(height(t->left)-height(t->right)==2)//在左子树插入结点后,不可能右子树比左子树高2
if(value<t->left->value)
leftSingleRotation(t);//左单旋转
else
leftDoubleRotation(t);//左双旋转
else//只需要重新计算其高度
t->height=max(height(t->left),height(t->right))+1;
}
else if(value>t->value)
{
insert(value,t->right);
if(height(t->right)-height(t->left)==2)
if(value>t->right->value)
rightSingleRotation(t);//右单旋转
else
rightDoubleRotation(t);//右双旋转
else//只需要重新计算其高度
t->height=max(height(t->left),height(t->right))+1;
}
}
avlNode *root=NULL;
int main()
{
int N,value;
cin>>N;
for(int i=0;i<N;++i)
{
cin>>value;
insert(value,root);
}
cout<<root->value<<endl;
return 0;
}
加个尾巴(AVL Tree的删除部分)
void remove(int value,avlNode* &root)
{//默认avl树中不存在相同的树
if(!root)return;//树为空,不做处理
if(value<root->value)
{
remove(value,root->left);
if(height(root->right)-height(root->left)==2)//删除节点以后对高度的重新调整
{
//右子树比左子树高2,那么在删除操作之前右子树比左子树高1,即右子树必不为空
avlNode *s=root->right;
if(height(s->left)>height(s->right))
rightDoubleRotation(root);//右双旋转
else
rightSingleRotation(root);//右单旋转
}
else
root->height=max(height(root->left),height(root->right))+1;
}
else if(value>root->value)
{
remove(value,root->right);
if(height(root->left)-height(root->right)==2)
{
avlNode *s=root->left;
if(height(s->right)>height(s->left))
leftDoubleRotation(root);//左双旋转
else
leftSingleRotation(root);//左单旋转
}
else
root->height=max(height(root->left),height(root->right))+1;
}
else
{
if(root->left&&root->right)//在这个节点中填充子树中这个节点值的前序(A)或后继(B),然后在对应子树中删除A/B
{
if(height(root->left)>height(root->right))
{
//左子树中的最大值的索引
root->value=maxNode(root->left)->value;
remove(root->value,root->left);
}
else
{
//右子树中的最小值的索引
root->value=minNode(root->right)->value;
remove(root->value,root->right);
}
}
else
{
avlNode *s=root;
root=root->left?root->left:root->right;
delete s;
}
}
}