PAT (Advanced Level) Practise 1066 Root of AVL Tree (25)

来源:互联网 发布:怎样软件编写 编辑:程序博客网 时间:2024/06/04 18:30

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:
588 70 61 96 120
Sample Output 1:
70
Sample Input 2:
788 70 61 96 120 90 65
Sample Output 2:
88


题意:将n个数插入AVL树中,输出树的根节点


#include <iostream>  #include <cstdio>  #include <cstring>  #include <string>  #include <algorithm>  #include <cmath>  #include <map>   #include <set>  #include <stack>  #include <queue>  #include <vector>  #include <bitset>  #include <functional>  using namespace std;#define LL long long  const int INF = 0x3f3f3f3f;const int N = 1e3 + 10;int n, x;int rt,sz; //根节点;总结点个数,用于建立新节点  int son[N][2]; //记录左右儿子的标号  int h[N],a[N];  //记录该节点向下最远的高度,用于维持avl数的平衡 ; 记录节点的值,维持插入需要  int f[N];  //记录节点的父亲节点标号  int node(int x, int fa)//数组模拟,建立新节点,父亲节点为fa,值为x,此时高度为1,没有子节点。 {a[sz] = x; f[sz] = fa; h[sz] = 1; memset(son[sz], 0,sizeof son[sz]); return sz++;}void Count(int x)//重新计算该节点高度{h[x] = max(h[son[x][0]], h[son[x][1]]) + 1;}void rotate(int x, int k)//旋转操作,x为节点编号,k为旋转类型,k=1时为右旋,k=0是为左旋  {int y = f[x]; son[y][!k] = son[x][k];if (son[x][k]) f[son[x][k]] = y;if (f[y]) son[f[y]][y == son[f[y]][1]] = x;f[x] = f[y]; f[y] = x; son[x][k] = y;Count(y); Count(x);}/*调整过程,根据avl树的性质,如果某个节点的左右高度差超过1,那么进行调整需要注意的是,avl树的旋转都是三个节点之间的,x,F[x],F[F[x]]并且分为两种,即x和F[x]都是同方向的,那么将F[x]向上旋转即可。如果是不同方向,那么将x连续向上旋转两次。*/int change(int x){for (int i = f[f[x]]; i; i = f[f[x]]){Count(f[x]); Count(i);if (abs(h[son[i][0]] - h[son[i][1]]) > 1){int y = x == son[f[x]][0], z = f[x] == son[i][0];y^z ? (rotate(x, y), rotate(x, z)) : rotate(f[x], z);}else x = f[x];}while (f[x]) { Count(x); x = f[x]; }return x;}void insert(int &rt, int x)//插入过程,像普通的排序二叉树一样插入,最后进行调整。  {if (!rt) { rt = node(x, 0); return; }for (int i = rt;; i = son[i][a[i] < x]){if (son[i][a[i] < x]) continue;son[i][a[i] < x] = node(x, i);rt = change(son[i][a[i] < x]); return;}}int main(){while (~scanf("%d",&n)){rt = 0; sz = 1;for(int i=1; i<=n; i++)scanf("%d",&x), insert(rt, x);printf("%d\n", a[rt]);}return 0;}

阅读全文
0 0
原创粉丝点击