好不容易整理吸收了自己写的习惯 的AVL树建树模板,保存一下~
struct Node
{
int value;
Node *left,*right;
Node(int v)
{
value=v;
left=right=NULL;
}
}*root=NULL;
//左旋和右旋的灵魂就是——新王交接,父承子业
//转一次的root,就是旧王,新王是他儿子
//转两次的root,他的儿子是转第一次的旧王,root自己是转第二次的旧王
//ll中左子无敌,rr中右子无敌
//lr中左子必死;rl中右子必死
Node* ll(Node *root)//插在左子树左边,是右旋——root是旧王,左子新王
{
Node *son=root->left;//造反的新王
root->left=son->right;//旧王贬官,交接
son->right=root;//新王摸狗头
return son;//返回新王
}
Node* rr(Node *root)//插在右子树右边,是左旋——root是旧王,右子新王
{
//同上噢
Node *son=root->right;
root->right=son->left;
son->left=root;
return son;
}
//插在左子树的右边,是先左旋再右旋
//则root为旧王,但是root的左子却是左旋的旧王
Node* lr(Node *root)
{
root->left=rr(root->left);//先左旋
return ll(root);//再右旋
}
//插在右子树的左边,是先右旋再左旋
//则root为旧王,但是root的右子却是右旋的旧王
Node *rl(Node *root)
{
root->right=ll(root->right);
return rr(root);
}
//1、因为AVL树在插入过程中会进行旋转,
//所以对于任何root而言,其左右子树都可能发生旋转,并使得root的左右孩子更改
//所以要左右孩子要保持迭代更新
//2、旋转过程中,判断是否发生旋转,就是在高度差为2的root和root的孩子上,要求高
//综上所述要按照递归写法
int getH(Node *root)//得到节点高
{
if(!root)return 0;
int l=getH(root->left);
int r=getH(root->right);
return max(l,r)+1;
}
Node* insert(Node *root,int value)
{
if(!root)root=new Node(value);
else if(value<root->value)//左边
{
root->left=insert(root->left,value);//防止孩子旋转,物是人非
if(getH(root->left)-getH(root->right)==2)//因为插在左子树,所以要旋转也是左子树变长了
{
if(value<root->left->value)//在左子树的左子树上,是ll
root=ll(root);//新的王
else
root=lr(root);
}
}
else //右边
{
root->right=insert(root->right,value);//防止孩子旋转,物是人非
if(getH(root->right)-getH(root->left)==2)//因为插在右子树,所以要旋转也是右子树变长了
{
if(value>root->right->value)//在右子树的右子树上,是rr
root=rr(root);//新的王
else
root=rl(root);
}
}
return root;
}
void main()
{
int j;
cin>>n;
loop(i,0,n)root=insert(root,j);
}