PTA 5-6 Root of AVL Tree (25) - 树 - 平衡二叉树
题目:http://pta.patest.cn/pta/test/16/exam/4/question/668
PTA - Data Structures and Algorithms (English) - 5-6
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.
LL:RR:
RL:
LR:
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. 树的结点结构
1 2 3 4 5 6 7 | typedef struct node { int data; node* left; node* right; int height; }AVLTreeNode,*AVLTree; |
2. 函数声明
1 2 3 4 5 6 7 8 | int GetHeight(AVLTree A) //获取当前树高 int Max( int x, int y) //用于更新树高 //以下操作返回调整后的AVL树 AVLTree SingleL_Rotation(AVLTree A) //左单旋:LL AVLTree SingleR_Rotation(AVLTree A) //右单旋:RR AVLTree DoubleLR_Rotation(AVLTree A) //右左双旋:RL AVLTree DoubleRL_Rotation(AVLTree A) //左右双旋:LR AVLTree AVL_Insertion( int x,AVLTree T) //将x插入AVL树T中 |
3. 函数实现 (以左旋为例):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | //左单旋:LL AVLTree SingleL_Rotation(AVLTree A) { //!注:A必须有一个左子节点B //!左单旋后,更新A和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; } //左右双旋;LR AVLTree DoubleLR_Rotation(AVLTree A) { //!注:A必须有一个左子结点B,且B必须有一个右子节点C //!做两次单旋,返回新的根节点:C A->left=SingleR_Rotation(A->left); //!B和C做右单旋,返回C return SingleL_Rotation(A); //!A和做左单旋,返回C } |
完整代码:
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 110 111 112 113 114 115 | #include <iostream> using namespace std; typedef struct node { int data; node* left; node* right; int height; }AVLTreeNode,*AVLTree; int GetHeight(AVLTree A) { if (A==NULL) return -1; return A->height; } int Max( int x, int y) { return (x>y)?x:y; } //!左单旋:LL AVLTree SingleL_Rotation(AVLTree A) { //!注:A必须有一个左子节点B //!左单旋后,更新A和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; } //!右单旋:RR AVLTree SingleR_Rotation(AVLTree A) { AVLTree C=A->right; A->right=C->left; C->left=A; A->height=Max(GetHeight(A->left),GetHeight(A->right))+1; C->height=Max(A->height,GetHeight(C->right))+1; return C; } //!左右双旋;LR AVLTree DoubleLR_Rotation(AVLTree A) { //!注:A必须有一个左子结点B,且B必须有一个右子节点C //!做两次单旋,返回新的根节点:C A->left=SingleR_Rotation(A->left); //!B和C做右单旋,返回C return SingleL_Rotation(A); //!A和做左单旋,返回C } //!右左双旋:RL AVLTree DoubleRL_Rotation(AVLTree A) { A->right=SingleL_Rotation(A->right); return SingleR_Rotation(A); } //!将x插入AVL树T中,并且返回调整后的AVL树 AVLTree AVL_Insertion( int x,AVLTree T) { if (!T) //!若插入空树,则新建包含一个节点的树 { T= new AVLTreeNode; T->data=x; T->height=0; T->left=T->right=NULL; } else if (x<T->data) //!插入T的左子树 { T->left=AVL_Insertion(x,T->left); if (GetHeight(T->left)-GetHeight(T->right)==2) { //!需左旋 if (x<T->left->data) T=SingleL_Rotation(T); //!左单旋:LL else T=DoubleLR_Rotation(T); //!左右双旋:LR } } else if (x>T->data) //!插入T的右子树 { T->right=AVL_Insertion(x,T->right); if (GetHeight(T->left)-GetHeight(T->right)==-2) { //!需右旋 if (x>T->right->data) T=SingleR_Rotation(T); //!右单旋:RR else T=DoubleRL_Rotation(T); //!右左双旋:RL } } else //! x==T->data, 无需插入 return T; //!更新树高 T->height=Max(GetHeight(T->left),GetHeight(T->right))+1; return T; } int main() { int n,x; cin >> n; AVLTree root=NULL; for ( int i=0;i<n;i++) { cin >> x; root=AVL_Insertion(x,root); } cout << root->data << endl; return 0; } |
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 智能桌面机器人:用.NET IoT库控制舵机并多方法播放表情
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 开发者新选择:用DeepSeek实现Cursor级智能编程的免费方案
· Tinyfox 发生重大改版
· 独立开发经验谈:如何通过 Docker 让潜在客户快速体验你的系统
· 小米CR6606,CR6608,CR6609 启用SSH和刷入OpenWRT 23.05.5
· 近期最值得关注的AI技术报告与Agent综述!