总结:
----第一次写---妄图用数组来完成--事实证明是不现实的。。。。。
本代码参考:https://www.liuchuo.net/archives/2178
总结第一次失败的教训:
1.没有理解好rotate的精髓,用数组麻烦得多
2.整体代码结构不是特别清晰,通过ac这道题,让我加深了对avl树的理解,以及对树整章的理解。
3.这代码难点主要是对插入后的判断和调整,判断主要是每插入一个点就判断这个点往上所有的节点是否满足左右子树之差小于等于1,柳神代码中巧妙地地方在于通过插入过程的判断插哪个位置----就可以得出矛盾类型---进而得出调整类型
还有就是LR旋转和RL柳神递归我没想到。
4,最后就是只有代码才不会骗人,在理解了这个知识点过后,本来以为写代码很轻松,但是真正写的时候各种问题,动手很重要啊!
代码思路就不贴了,看别人的代码就能弄清楚思路。如果不懂的欢迎留言,我会努力让你理解的~~~~~~~~~~~
AC代码:
#include<iostream>
using namespace std;
typedef struct node* TT;
struct node{
int data;
TT left, right;
};
int gethigh(TT root)
{
int ans=0, hl=1, hr=1;
if (root == NULL)return 0;
if (root->left != NULL)hl = 1 + gethigh(root->left);
if (root->right != NULL)hr = 1 + gethigh(root->right);
ans = hl > hr ? hl : hr;
return ans;
}
TT rotateLL(TT root)
{
TT t = root->left;
root->left = t->right;
t->right = root;
return t;
}
TT rotateRR(TT root)
{
TT t = root->right;
root->right = t->left;
t->left = root;
return t;
}
TT rotateLR(TT root)
{
TT t = root->left->right;
TT s = root->left;
s->right = t->left;
root->left = t->right;
t->left = s;
t->right = root;
return t;
}
TT rotateRL(TT root)
{
TT s = root->right;
TT t = root->right->left;
root->right = t->left;
s->left = t->right;
t->left = root;
t->right = s;
return t;
}
TT creat(TT root,int data)
{
if (root == NULL)
{
root = new node();
root->data = data;
root->left = NULL;
root->right = NULL;
}
else{
if (data > root->data)
{
root->right=creat(root->right, data);
if (gethigh(root->right) - gethigh(root->left) > 1)
{
root = root->right->data < data ? rotateRR(root) : rotateRL(root);
}
}
else if (data < root->data)
{
root->left = creat(root->left,data);
if (gethigh(root->left) - gethigh(root->right)>1)
{
root = root->left->data>data ? rotateLL(root) : rotateLR(root);
}
}
}
return root;
}
int main()
{
int n;
cin >> n;
TT root=NULL;
for (int i = 0; i < n; i++)
{
int data;
cin >> data;
root=creat(root,data);
}
cout << root->data;
return 0;
}