1. 程式人生 > >PTA (Advanced Level)1066 Root of AVL Tree

PTA (Advanced Level)1066 Root of AVL Tree

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樹模板題要求按輸入建立AVL樹即在二叉搜尋樹葉子結點最大高度差大於等於二的時候進行左旋或右旋進行結構優化使結點深度保持在O(logn)的級別,輸出AVL樹根結點。
  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 typedef int dataType;
  4 vector<dataType> data;
  5 struct node{
  6     dataType data;
  7     int height; //AVL樹結點比起普通二叉搜尋樹需要記錄height
  8     node *leftChild;
  9     node * rightChild;
 10     node(){
 11         height = 1;
 12         leftChild = NULL;
 13         rightChild = NULL;
 14     }
 15 };
 16 int getHeight(node *root){  //獲取高度
 17     if(root == NULL)  
 18         return 0;
 19     else
 20         return root->height;
 21 }
 22 int getBalanceFactor(node *root){   //獲取樹的葉子結點高度差左高為正右高為負
 23     return getHeight(root->leftChild) - getHeight(root->rightChild);
 24 }
 25 int updateHeight(node *root){   //更新高度
 26     root->height = max(getHeight(root->leftChild),getHeight(root->rightChild)) + 1;
 27 }
 28 void leftRotation(node *&root){ //左旋
 29     node *temp = root->rightChild;      //root指向先前根結點temp指向右子樹根結點
 30     root->rightChild = temp->leftChild; //temp指向根結點的右子樹,所以其所有結點都大於根結點
 31     //由於在左旋中需要使temp成為新的根結點,所以將root右子樹指向temp左子樹,再讓temp左子樹指向root
 32     temp->leftChild = root;
 33     //更新root與temp的樹高
 34     updateHeight(root);
 35     updateHeight(temp);
 36     root = temp;    //temp成為新的根結點
 37 }
 38 void rightRotation(node *&root){    //右旋思路同左旋
 39     node *temp = root->leftChild;
 40     root->leftChild = temp->rightChild;
 41     temp->rightChild = root;
 42     updateHeight(root);
 43     updateHeight(temp);
 44     root = temp;
 45 }
 46 void insertAVLTree(node *&root, int x){ //插入結點
 47     if(root == NULL){   //找到插入位置
 48         root = new node();
 49         root->data = x;
 50         return;
 51     }
 52     if(root->data == x){    //結點已存在
 53         return;
 54     }else if(root->data > x){   //要插入的資料比根結點權值小
 55         insertAVLTree(root->leftChild, x);  //插入左子樹
 56         updateHeight(root);
 57         if(getBalanceFactor(root) == 2){
 58             if(getBalanceFactor(root->leftChild) == 1){
 59                 rightRotation(root);
 60             }else if(getBalanceFactor(root->leftChild) == -1){
 61                 leftRotation(root->leftChild);
 62                 rightRotation(root);
 63             }
 64         }
 65     }else if(root->data < x){   //要插入的資料比根結點權值大
 66         insertAVLTree(root->rightChild, x); //插入右子樹
 67         updateHeight(root);
 68         if(getBalanceFactor(root) == -2){
 69             if(getBalanceFactor(root->rightChild) == -1){
 70                 leftRotation(root);
 71             }else if(getBalanceFactor(root->rightChild) == 1){
 72                 rightRotation(root->rightChild);
 73                 leftRotation(root);
 74             }
 75         }
 76     }
 77 }
 78 node *createAVLTree(){
 79     node *root = NULL;
 80     for(vector<dataType>::iterator it = data.begin(); it != data.end(); it++){
 81         insertAVLTree(root, *it);
 82     }
 83     return root;
 84 }
 85 /*void preorder(node *root){
 86     if(root == NULL)
 87         return;
 88     cout << root -> data << " ";
 89     preorder(root -> leftChild);
 90     preorder(root -> rightChild);
 91 }*/
 92 int main()
 93 {
 94     int n;
 95     while(scanf("%d", &n) != EOF){
 96         data.clear();
 97         for(int i = 0; i < n; i++){
 98             dataType temp;
 99             scanf("%d", &temp);
100             data.push_back(temp);
101         }
102         node *root = createAVLTree();
103         //preorder(root);
104         //cout << endl;
105         printf("%d\n", root->data);
106     }
107     return 0;
108 }