1066. Root of AVL Tree (25)

时间限制
100 ms

内存限制
65536 kB

代码长度限制
16000 B

判题程序
Standard

作者
CHEN, Yue

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
数据结构听到AVL就头大,根本不知道这么做的意义;这次看着博文和别人AC的代码写了这个。以前很喜欢用链表的;但是现在有点不喜欢,比如地址空间会很大的。然后就用int带代替指针;整个数组化。AVL左旋右旋,旋来旋去就那几行代码。重点的是那个有回溯的那段。还有各种细节;
代码中有详细的注释。顺便(PS:我通过tag动态化,直接就弄成看似一种旋转的了)
有四种种情况可能导致二叉查找树不平衡,分别为:(1)LL:插入一个新节点到根节点的左子树(Left)的左子树(Left),导致根节点的平衡因子由1变为2(2)RR:插入一个新节点到根节点的右子树(Right)的右子树(Right),导致根节点的平衡因子由-1变为-2(3)LR:插入一个新节点到根节点的左子树(Left)的右子树(Right),导致根节点的平衡因子由1变为2(4)RL:插入一个新节点到根节点的右子树(Right)的左子树(Left),导致根节点的平衡因子由-1变为-2针对四种种情况可能导致的不平衡,可以通过旋转使之变平衡。有两种基本的旋转:(1)左旋转:将根节点旋转到(根节点的)右孩子的左孩子位置(2)右旋转:将根节点旋转到(根节点的)左孩子的右孩子位置
联动AVL  http://dongxicheng.org/structure/avl/

评测结果

时间 结果 得分 题目 语言 用时(ms) 内存(kB) 用户
8月13日 21:56 答案正确 25 1066 C++ (g++ 4.7.2) 1 308 datrilla

测试点

测试点 结果 用时(ms) 内存(kB) 得分/满分
0 答案正确 1 308 4/4
1 答案正确 1 308 4/4
2 答案正确 1 308 4/4
3 答案正确 1 308 4/4
4 答案正确 1 308 4/4
5 答案正确 1 308 4/4
6 答案正确 1 308 1/1
#include <iostream>
#include<vector>
using namespace std;
struct List
{int value;int left_right;int l0_r1[2];
};
int Height(vector<List>*AVLtree, int node,int tag)/*如果node的child【左tag=0】【右tag=1】不存在那么返回高度-1 */
{                                                 /*如果node存在,那么必然返回对应结点child的|left-right|>=0*/int child = (*AVLtree)[node].l0_r1[tag];      /*PS:本来一直样例不行,原来是存在时错误返回node前一轮的了*/if (child == -1)return -1;else return (*AVLtree)[child].left_right;
}
int returnmax(int a, int b)/*对于root返回他的左右结点高度最高的*/
{if (a > b)return a; else return b;
}
int rotate(vector<List>*AVLtree,int tag,int Root,int child)/*tag=0,左旋:带入的child为Root的右。[1-tag]→;[tag]←*/
{                                                          /*tag=1,右旋:带入的child为Root的左。[1-tag]←;[tag]→*/(*AVLtree)[Root].l0_r1[1-tag] = (*AVLtree)[child].l0_r1[tag];(*AVLtree)[child].l0_r1[tag] = Root;(*AVLtree)[Root].left_right = returnmax(Height(AVLtree, Root, tag), Height(AVLtree, Root, 1-tag))+1;(*AVLtree)[child].left_right = returnmax(Height(AVLtree, child, tag), Height(AVLtree, child, 1 - tag))+1; return child; /*旋转以后Root和Child身份互换了,并且稳定,需要更新此时他们的高度,一遍回溯的时候由其他Root使用*/
}
int insertnew(vector<List>*AVLtree, int Root,int N)
{ int tag;int child;if (Root == N)     return Root; /*只有一个结点,显然这个结点就是Root【PS第一次的Root,在主函数有初始化为最开始的N-1】*/else{if ((*AVLtree)[N].value < (*AVLtree)[Root].value)/*本来已经存在结点,这里用来判断是往左走tag=0,或者往右走tag=1*/tag = 0;else tag = 1;if ((*AVLtree)[Root].l0_r1[tag] != -1)/*如果此次走的Root的该方向还有下个结点,DFS走下去;否则截止*/{child = (*AVLtree)[Root].l0_r1[tag] = insertnew(AVLtree, (*AVLtree)[Root].l0_r1[tag], N); /*这里出来以后的child为新数往当前Root走的方向稳定后的【左tag=0】【右tag=1】结点*/if (Height(AVLtree, Root, tag) - Height(AVLtree, Root, 1 - tag) == 2){ if ((   (*AVLtree)[N].value<(*AVLtree)[Root].value &&(*AVLtree)[N].value<(*AVLtree)[child].value  )||(  (*AVLtree)[N].value>=(*AVLtree)[Root].value && (*AVLtree)[N].value>=(*AVLtree)[child].value)){Root=rotate(AVLtree,1-tag, Root, child); }/*R  L  如果新放入的在这个child和root的同一边左左(右右),那么只要一次对应左(右)旋*/ else   { child = rotate(AVLtree,tag, child, (*AVLtree)[child].l0_r1[1-tag]);Root = rotate(AVLtree,1-tag, Root, child);/**/}/*LR RL  否则在Root左,child右;左旋后右旋;在Root右,在child左,右旋后左旋*/} }else child=(*AVLtree)[Root].l0_r1[tag] = N;  /*这里是截止的,即新进的位置*/ }  (*AVLtree)[Root].left_right = returnmax(Height(AVLtree, Root, tag), Height(AVLtree, Root, 1 - tag)) + 1;return Root;
}
int main()
{int N,Root;cin >> N;  vector<List>AVLtree(N);Root = N - 1;while (N--){cin >> AVLtree[N].value;AVLtree[N].left_right = 0;AVLtree[N].l0_r1[0] = AVLtree[N].l0_r1[1] = -1;Root = insertnew(&AVLtree, Root, N); }cout<< AVLtree[Root].value << endl;system("pause");return 0;
}


上面这种思路用[tag]的,有点反人类,很难理清。其实个人觉得分开写或许会更便于理解和书写。
再转一个大佬们的。

#include <cstdio>
#define max(a, b) (((a) > (b)) ? (a) : (b))
struct node {int val;struct node *left, *right;
};
node *rotateLeft(node *root) {node *t = root->right;root->right = t->left;t->left = root;return t;
}
node *rotateRight(node *root) {node *t = root->left;root->left = t->right;t->right = root;return t;
}
node *rotateLeftRight(node *root) {root->left = rotateLeft(root->left);return rotateRight(root);
}
node *rotateRightLeft(node *root) {root->right = rotateRight(root->right);return rotateLeft(root);
}
int getHeight(node *root) {if(root == NULL) return 0;return max(getHeight(root->left), getHeight(root->right)) + 1;
}
node *insert(node *root, int val) {if(root == NULL) {root = new node();root->val = val;root->left = root->right = NULL;} else if(val < root->val) {root->left = insert(root->left, val);if(getHeight(root->left) - getHeight(root->right) == 2)root = val < root->left->val ? rotateRight(root) : rotateLeftRight(root);} else {root->right = insert(root->right, val);if(getHeight(root->left) - getHeight(root->right) == -2)root = val > root->right->val ? rotateLeft(root) : rotateRightLeft(root);}return root;
}
int main() {int n, val;scanf("%d", &n);node *root = NULL;for(int i = 0; i < n; i++) {scanf("%d", &val);root = insert(root, val);}printf("%d", root->val);return 0;
}

												

PAT 1066. Root of AVL Tree (25) 回レ!雪月AVL相关推荐

  1. PAT甲级1066 Root of AVL Tree (25分):[C++题解]建立平衡树(AVL树)

    文章目录 题目分析 题目链接 题目分析 图片来源:acwing 分析 平衡树(AVL树)是平衡二叉搜索树的简称,当然需要满足二叉搜索树的性质,左子树小于根,根小于等于右子树:然后还要满足平衡树的基本特 ...

  2. pat04-树4. Root of AVL Tree (25)

    04-树4. Root of AVL Tree (25) 时间限制 100 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue An A ...

  3. 1066 Root of AVL Tree (25 分)【难 / 知识点: 平衡树 未完成】

    https://pintia.cn/problem-sets/994805342720868352/problems/994805404939173888 平衡树之前学过,不过有忘完了,有时间补吧

  4. PAT1066 Root of AVL Tree (25)(AVL树)

    题意: 给出一系列要插入平衡搜索二叉树的数,要求输出最后的根节点 思路: 没其他办法,完完全全是AVL树的插入节点模拟,这题就不会写,看别人代码写的. #include<iostream> ...

  5. PAT甲级1123 Is It a Complete AVL Tree (30分):[C++题解]建立平衡树、bfs,判完全二叉树

    文章目录 题目分析 题目链接 题目分析 来源:pat网站 本题作为进阶题,它的基础知识点如下几题. PAT甲级1066 Root of AVL Tree (25分):[C++题解]建立平衡树(AVL树 ...

  6. 1066 Root of AVL Tree——PAT甲级 | 参考mooc实现完整代码

    Root of AVL Tree  2013年浙江大学计算机学院免试研究生上机考试真题,是关于AVL树的基本训练. 原题链接:PTA | 程序设计类实验辅助教学平台 题目描述 AVL 树是一种自平衡的 ...

  7. PAT A1066 Root of AVL Tree ——春水碧于天,画船听雨眠

    PAT A1066 Root of AVL Tree AVL这东西记一次忘一次,每次看就像披着初恋外衣的旧情人(or reverse) 以下应该是较为标准的模板方法,只是好久没有用过指针了,所以写了个 ...

  8. 【PAT A1066】Root of AVL Tree

    #include <cstdio> #include <algorithm> using namespace std;struct node {int v, height; / ...

  9. PAT (Advanced Level) Practice 1043 Is It a Binary Search Tree (25 分) 凌宸1642

    PAT (Advanced Level) Practice 1043 Is It a Binary Search Tree (25 分) 凌宸1642 题目描述: A Binary Search Tr ...

最新文章

  1. 理解Android进程创建流程
  2. 再转弯曲评论上的一篇关于SOC的文章
  3. php pdo参数化,php – 如何正确地使用PDO对象的参数化SELECT查询
  4. oa服务器怎么修改域名,oa域名服务器配置
  5. 程序员会写诗是怎样的体验
  6. 30万条数据,搜索文本字段的各种方式对比
  7. 【Day13】说一下 Vue 组件的通信方式都有哪些?(父子组件,兄弟组件,多级嵌套组件等等)
  8. 漫步线性代数二十三——行列式公式
  9. 洛谷 P2622 关灯问题II (状态压缩+BFS)
  10. indexed true mysql_一行代码,搞定浏览器数据库 IndexedDB
  11. 【BIEE】由于排序顺序不兼容,集合操作失败
  12. 用C语言编写贪吃蛇小游戏
  13. 串口服务器通讯协议,串口服务器的组成和应用实例
  14. 我的网关、子网掩码、DNS1、DNS2是什么
  15. VTK 三维 重建 切割 三维点云
  16. 祝福我的家人朋友永远平安健康
  17. 基于Swing的Java学生成绩管理系统
  18. mocha 测试 mysql_GitHub - nodejs-xx/lei: 整合Express mysql ioredis ejs 的一开发框架,使用mocha对api进行测试...
  19. 关于我国电子商务立法的思考
  20. 服务一直处于‘启动中‘,无法关闭(已解决)

热门文章

  1. 什么叫组网_小米科普:一文看懂路由器上的 Mesh 组网是什么
  2. 成长了,记录一下,增值税发票识别写入excel文件里
  3. bilibili学习
  4. 【计算机毕业设计】034学生请假系统设计与实现
  5. 怎样将PDF转成EXCEL
  6. [1005]pika 线程不安全
  7. 学会这几点,不懂代码也能做出炫酷可视化大屏!
  8. 你以为国人的数学很好?实际上数学思维特别差
  9. Kali Linux查看信息
  10. JAVA导出EXCEL实现