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 (≤) which is the total number of keys to be inserted. Then Ndistinct 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

AVL树作用:
  对于正常二叉搜索树建立过程,以第一个结点为根结点,若输入的结点权值大于第一个结点则插入右子树,小于第一个结点则插入左子树。若遇到出入数据为有序的情况,普通二叉搜索树就会建立一个长链式的树,其查询复杂度就会达到O(n),如以{1, 2, 3, 4 ,5 ,6, 7, 8, 9, 10}建立的二叉搜索树:

若要保持查询复杂度为O(logn)则需要建立AVL树,只需在插入过程中通过左旋右旋操作保证叶子结点的最大高度差不超过1,以{1, 2, 3, 4 ,5 ,6, 7, 8, 9, 10}建立AVL树:


解题思路:
  AVL树模板题要求按输入建立AVL树即在二叉搜索树叶子结点最大高度差大于等于二的时候进行左旋或右旋进行结构优化使结点深度保持在O(logn)的级别,输出AVL树根结点。

 
 #include <bits/stdc++.h>
using namespace std;
typedef int dataType;
vector<dataType> data;
struct node{
dataType data;
int height; //AVL树结点比起普通二叉搜索树需要记录height
node *leftChild;
node * rightChild;
node(){
height = ;
leftChild = NULL;
rightChild = NULL;
}
};
int getHeight(node *root){ //获取高度
if(root == NULL)
return ;
else
return root->height;
}
int getBalanceFactor(node *root){ //获取树的叶子结点高度差左高为正右高为负
return getHeight(root->leftChild) - getHeight(root->rightChild);
}
int updateHeight(node *root){ //更新高度
root->height = max(getHeight(root->leftChild),getHeight(root->rightChild)) + ;
}
void leftRotation(node *&root){ //左旋
node *temp = root->rightChild; //root指向先前根结点temp指向右子树根结点
root->rightChild = temp->leftChild; //temp指向根结点的右子树,所以其所有结点都大于根结点
//由于在左旋中需要使temp成为新的根结点,所以将root右子树指向temp左子树,再让temp左子树指向root
temp->leftChild = root;
//更新root与temp的树高
updateHeight(root);
updateHeight(temp);
root = temp; //temp成为新的根结点
}
void rightRotation(node *&root){ //右旋思路同左旋
node *temp = root->leftChild;
root->leftChild = temp->rightChild;
temp->rightChild = root;
updateHeight(root);
updateHeight(temp);
root = temp;
}
void insertAVLTree(node *&root, int x){ //插入结点
if(root == NULL){ //找到插入位置
root = new node();
root->data = x;
return;
}
if(root->data == x){ //结点已存在
return;
}else if(root->data > x){ //要插入的数据比根结点权值小
insertAVLTree(root->leftChild, x); //插入左子树
updateHeight(root);
if(getBalanceFactor(root) == ){  //插入左子树时只可能出现左子树比右子树高的情况
if(getBalanceFactor(root->leftChild) == ){  //若左子树的左子树较高直接右旋
rightRotation(root);
}else if(getBalanceFactor(root->leftChild) == -){  //若左子树中右子树较高则将其通过右旋转化为左子树高的情况  种情况详见下图
leftRotation(root->leftChild);
rightRotation(root);
}
}
}else if(root->data < x){ //要插入的数据比根结点权值大
insertAVLTree(root->rightChild, x); //插入右子树
updateHeight(root);
if(getBalanceFactor(root) == -){
if(getBalanceFactor(root->rightChild) == -){
leftRotation(root);
}else if(getBalanceFactor(root->rightChild) == ){
rightRotation(root->rightChild);
leftRotation(root);
}
}
}
}
node *createAVLTree(){
node *root = NULL;
for(vector<dataType>::iterator it = data.begin(); it != data.end(); it++){
insertAVLTree(root, *it);
}
return root;
}
/*void preorder(node *root){
if(root == NULL)
return;
cout << root -> data << " ";
preorder(root -> leftChild);
preorder(root -> rightChild);
}*/
int main()
{
int n;
while(scanf("%d", &n) != EOF){
data.clear();
for(int i = ; i < n; i++){
dataType temp;
scanf("%d", &temp);
data.push_back(temp);
}
node *root = createAVLTree();
//preorder(root);
//cout << endl;
printf("%d\n", root->data);
}
return ;
}
左子树的左子树较高

左子树的右子树较高


最新文章

  1. 《JS语言精粹》学习笔记 函数部分の闭包
  2. ionic+angularjs开发hybrid App(环境配置+创建测试项目)
  3. PPT开发 * .pps 文件类型
  4. 解析nginx负载均衡
  5. 【BZOJ】【2157】旅游
  6. Java设计模式15:常用设计模式之享元模式(结构型模式)
  7. ASP.NET 发送电子邮件简介
  8. iOS CoCoa编程中视图控制器与视图类(转)
  9. windows系统下搭建Python开发环境
  10. android系统将普通应用升级为系统应用
  11. 解决Ubuntu中phpmyadmin对数据上传上限2M
  12. 《SpringMVC从入门到放肆》四、SpringMVC配置式开发(处理器映射器)
  13. MySql主键自动生成,表、实体、C#调用方法
  14. C++: 类成员初始化列表语法
  15. [翻译]LVM中逻辑卷的最大大小限制
  16. RAND_MAX
  17. C# WinForm窗体控件Panel修改边框颜色以及边框宽度方法
  18. 【Spring】20、使用TransactionSynchronizationManager在spring事务提交之后进行一些操作。
  19. 如何重置Sitecore CMS中的管理员密码
  20. iOS: 获取UITableViewCell上添加的子控件对应的cell

热门文章

  1. UnicodeEncodeError:&#39;latin-1&#39; codec can&#39;t encode characters in position 0-1: ordinal not in range(256)
  2. MvvmLight框架使用入门(三)
  3. Keepalived_vrrp: ip address associated with VRID not present in received packet
  4. mysql遇到的问题:can&#39;t creat/write to file &quot;/var/mysql/xxxx.MYI&quot;
  5. Java50道经典习题-程序17 猴子吃桃问题
  6. 【OCP-12c】2019年CUUG OCP 071考试题库(80题)
  7. String类的操作方法
  8. java 获取一个整数的各个位数
  9. spring包下载方法
  10. 洛谷P5280 [ZJOI2019]线段树(线段树)