[PAT] A1066 Root of AVL Tree

tech2022-09-05  94

(要熟练!)

题目大意

输入一个结点序列,按照这个序列输入,每插入一次都自动调整为平衡二叉搜索树AVL。求最终形成的AVL树根的值。 在AVL树中,任何节点的两个子子树的高度最多相差一个;如果在任何时候它们相差多于一个,则重新平衡以恢复此属性。

思路

熟练掌握建立AVL的代码即可。

在判断子结点平衡因子的时候,为1和为-1两个if必须是互斥的。一开始没写else,会出现进入第一个if后平衡因子的值改变了又进入第二个if的情况。 debug了一早上,一直以为是别的问题,没注意到这个细节...但发现可以不必在结构体中保存每个结点的高度,需要判断的时候每次递归求解即可。 建立树的过程还不够熟练,一定要多多再写几遍。

AC代码

#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include <cstdio> #include <vector> #include <map> #include<algorithm> #include<queue> using namespace std; struct node { int key; node* lchild, * rchild; }; int getheight(node* root) { if (root == NULL)return 0; return max(getheight(root->lchild), getheight(root->rchild)) + 1; } int balance(node* root) { return getheight(root->lchild) - getheight(root->rchild); } void R(node*& root) { node* newroot = root->lchild; root->lchild = newroot->rchild; newroot->rchild = root; root = newroot; } void L(node*& root) { node* newroot = root->rchild; root->rchild = newroot->lchild; newroot->lchild = root; root = newroot; } void insert(node*& root, int number) { if (root == NULL) { root = new node;//注意细节 root->key = number; root->lchild = root->rchild = NULL; return; } if (number < root->key) { insert(root->lchild, number); if (balance(root) == 2) { if (balance(root->lchild) == 1)R(root); //一开始漏了“else”,可能出现进入上一个1的if后值改变了又进入第二个if的情况 else if (balance(root->lchild) == -1) { L(root->lchild); R(root); } } } else { insert(root->rchild, number); if (balance(root) == -2) { if (balance(root->rchild) == -1)L(root); else if (balance(root->rchild) == 1) { R(root->rchild); L(root); } } } } int main() { int i, n; scanf("%d", &n); int number; node* root = NULL; for (i = 0;i < n;i++) { scanf("%d", &number); insert(root, number); } printf("%d", root->key); return 0; }

最后附上一个按照算法笔记上写的(在节点中加入了参数height表示该结点的高度)代码

#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include <cstdio> #include <vector> #include <map> #include<algorithm> #include<queue> using namespace std; struct node { int key; node* lchild, * rchild; int height; }; int getheight(node* p) { if (p == NULL)return 0; return p->height; } int balance(node* root) { return getheight(root->lchild) - getheight(root->rchild); } void updateheight(node* root) { root->height = max(getheight(root->lchild), getheight(root->rchild)) + 1; } void R(node*& root) { node* newroot = root->lchild; root->lchild = newroot->rchild; newroot->rchild = root; updateheight(root);//记得更新高度!而且这里必须先更新root(因为它现在是newroot孩子)! updateheight(newroot); root = newroot; } void L(node*& root) { node* newroot = root->rchild; root->rchild = newroot->lchild; newroot->lchild = root; updateheight(root);//记得更新高度! updateheight(newroot); root = newroot; } void insert(node*& root, int number) { if (root == NULL) { root = new node;//注意细节 root->height = 1; root->key = number; root->lchild = root->rchild = NULL; return; } if (number <= root->key) { insert(root->lchild, number); updateheight(root); if (balance(root) == 2) { if (balance(root->lchild) == 1)R(root); else if (balance(root->lchild) == -1) { L(root->lchild); R(root); } } } else { insert(root->rchild, number); updateheight(root); if (balance(root) == -2) { if (balance(root->rchild) == -1)L(root); else if (balance(root->rchild) == 1) { R(root->rchild); L(root); } } } } int main() { int i, n; scanf("%d", &n); int number; node* root = NULL; for (i = 0;i < n;i++) { scanf("%d", &number); insert(root, number); } printf("%d", root->key); return 0; }
最新回复(0)