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
题意没什么好说的,一看就明白了。这题最主要是让我们学会平衡二叉树在插入节点的时候,如果平衡因子大于1了,这这时我们如何去写出代码将树翻转保持原来的平衡因子。而难点也在于这里,但是mooc课件中就已经给出了平衡翻转的代码,虽然只给出了ll和lr的但是我们模仿也很容易写出rr和rl 的,但是我们不能仅仅模仿写完这题就完事了,更需要从深层理解的角度去明白是如何翻转的,能够自己写出这四个翻转函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
#include<iostream> #include<malloc.h> using namespace std; typedef int ElementType; typedef struct AVLNode* Position; typedef Position AVLTree; /* AVL树类型 */ struct AVLNode { ElementType Data; /* 结点数据 */ AVLTree Left; /* 指向左子树 */ AVLTree Right; /* 指向右子树 */ int Height; /* 树高 */ }; int Max(int a, int b) { return a > b ? a : b; } // 返回树高,空树返回 -1 int GetHeight(AVLTree A) { return A == NULL ? -1 : A->Height; } AVLTree SingleRightRotation(AVLTree A); AVLTree SingleLeftRotation(AVLTree A) { /* 注意:A必须有一个左子结点B */ /* 将A与B做左单旋,更新A与B的高度,返回新的根结点B */ 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->Left), A->Height) + 1; return B; } AVLTree DoubleLeftRightRotation(AVLTree A) { /* 注意:A必须有一个左子结点B,且B必须有一个右子结点C */ /* 将A、B与C做两次单旋,返回新的根结点C */ /* 将B与C做右单旋,C被返回 */ A->Left = SingleRightRotation(A->Left); /* 将A与C做左单旋,C被返回 */ return SingleLeftRotation(A); } /*************************************/ /* 对称的右单旋与右-左双旋请自己实现 */ /*************************************/ AVLTree SingleRightRotation(AVLTree A) { // 此时根节点是 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->Left), A->Height) + 1; return B; // 此时 B 为根结点了 } AVLTree DoubleRightLeftRotation(AVLTree A) { A->Right = SingleLeftRotation(A->Right); return SingleRightRotation(A); } AVLTree Insert(AVLTree T, ElementType X) { /* 将X插入AVL树T中,并且返回调整后的AVL树 */ if (!T) { /* 若插入空树,则新建包含一个结点的树 */ T = (AVLTree)malloc(sizeof(struct AVLNode)); T->Data = X; T->Height = 0; T->Left = T->Right = NULL; } /* if (插入空树) 结束 */ else if (X < T->Data) { /* 插入T的左子树 */ T->Left = Insert(T->Left, X); /* 如果需要左旋 */ if (GetHeight(T->Left) - GetHeight(T->Right) == 2) if (X < T->Left->Data) T = SingleLeftRotation(T); /* 左单旋 */ else T = DoubleLeftRightRotation(T); /* 左-右双旋 */ } /* else if (插入左子树) 结束 */ else if (X > T->Data) { /* 插入T的右子树 */ T->Right = Insert(T->Right, X); /* 如果需要右旋 */ if (GetHeight(T->Left) - GetHeight(T->Right) == -2) if (X > T->Right->Data) T = SingleRightRotation(T); /* 右单旋 */ else T = DoubleRightLeftRotation(T); /* 右-左双旋 */ } /* else if (插入右子树) 结束 */ /* else X == T->Data,无须插入 */ /* 别忘了更新树高 */ T->Height = Max(GetHeight(T->Left), GetHeight(T->Right)) + 1; return T; } int main() { int n,tmp; cin >> n; AVLTree a=NULL; for (int i = 0; i < n; i++) { cin >> tmp; a = Insert(a, tmp); } cout << a->Data; } |