ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

P3369 【模板】普通平衡树 avl树数组版

2022-04-10 21:31:07  阅读:182  来源: 互联网

标签:rt rs int height avl P3369 ls 模板


P3369 【模板】普通平衡树

//avl数组版 
#include<bits/stdc++.h>
using namespace std;
const int maxn=100010;
struct avlnode{
	int val;
	int size;
	int cnt;
	int height;
	int ls;
	int rs;
}avl[maxn];
int root,tot;
int height(int rt)
{
	return avl[rt].height;
}
void pushup(int rt)
{
	avl[rt].size=avl[avl[rt].ls].size+avl[avl[rt].rs].size+avl[rt].cnt;
}
void LeftRotation(int &rt)
{
	int k;
	k=avl[rt].rs;
	avl[rt].rs=avl[k].ls;
	avl[k].ls=rt;
	avl[rt].height=max(height(avl[rt].ls),height(avl[rt].rs))+1;
	pushup(rt);
	avl[k].height=max(height(avl[k].ls),height(avl[k].rs))+1;
	pushup(k);
	rt=k;
}
void RightRotation(int &rt)
{
	int k;
	k=avl[rt].ls;
	avl[rt].ls=avl[k].rs;
	avl[k].rs=rt;
	avl[rt].height=max(height(avl[rt].ls),height(avl[rt].rs))+1;
	pushup(rt);
	avl[k].height=max(height(avl[k].ls),height(avl[k].rs))+1;
	pushup(k);
	rt=k;
}
int Newavl(int v)
{
	tot++;
	avl[tot].val=v;
	avl[tot].ls=avl[tot].rs=0;
	avl[tot].cnt=avl[tot].size=1;
	avl[tot].height=0;
	return tot;	
}
void preorder(int rt)
{
	if (rt!=0)
	{
		cout<<rt<<",ls"<<avl[rt].ls<<",rs"<<avl[rt].rs<<",cnt"<<avl[rt].cnt<<",size"<<avl[rt].size<<",height"<<avl[rt].height<<",val"<<avl[rt].val<<endl;
		preorder(avl[rt].ls);
		preorder(avl[rt].rs);		
	}
}
void inorder(int rt)
{
	if (rt!=0)
	{
		inorder(avl[rt].ls);
		for (int i=1;i<=avl[rt].cnt;++i) cout<<avl[rt].val<<" "; 
		inorder(avl[rt].rs);
	}
}
void insert(int &rt,int v)
{
	if (rt==0)
	{
		rt=Newavl(v); 
	}
	else if (avl[rt].val>v)
	{
		insert(avl[rt].ls,v);
		if (avl[avl[rt].ls].height-avl[avl[rt].rs].height==2)
		{
			int& k=avl[rt].ls;
			if (avl[avl[k].ls].height>avl[avl[k].rs].height)
			{
				RightRotation(rt);	
			}
			else
			{
				LeftRotation(k);
				RightRotation(rt);
			} 
		}
	}
	else
	{
		insert(avl[rt].rs,v);
		if (avl[avl[rt].ls].height-avl[avl[rt].rs].height==-2)
		{
			int& k=avl[rt].rs;
			if (avl[avl[k].ls].height<avl[avl[k].rs].height)
			{
				LeftRotation(rt);	
			}
			else
			{
				RightRotation(k);
				LeftRotation(rt);
			} 
		}
	}
	pushup(rt);
	avl[rt].height=max(avl[avl[rt].ls].height,avl[avl[rt].rs].height)+1;
}
int Maximum(int rt)
{
	if (rt==0)
	{
		return rt;
	}
	while(avl[rt].rs!=0)
	{
		rt=avl[rt].rs;
	}
	return rt;
}
int Minimum(int rt)
{
	if (rt==0)
	{
		return rt;
	}
	while(avl[rt].ls!=0)
	{
		rt=avl[rt].ls;
	}
	return rt;
}
void dele(int &rt,int v)
{
	if (rt==0) 
	{
		return ;
	}
	if (v<avl[rt].val)
	{
		dele(avl[rt].ls,v);
		avl[rt].height=max(height(avl[rt].ls),height(avl[rt].rs))+1;
		if (height(avl[rt].ls)-height(avl[rt].rs)==-2)
		{
			int &k=avl[rt].rs;
			if (height(avl[k].ls)>height(avl[k].rs))
			{
				RightRotation(k);
				LeftRotation(rt);
			}
			else
			{
				LeftRotation(rt);		
			}
		}
	}
	else if(v>avl[rt].val)
	{
		dele(avl[rt].rs,v);
		avl[rt].height=max(height(avl[rt].ls),height(avl[rt].rs))+1;
		if (height(avl[rt].ls)-height(avl[rt].rs)==2)
		{
			int &k=avl[rt].ls;
			if (height(avl[k].rs)>height(avl[k].ls))
			{
				LeftRotation(k);
				RightRotation(rt);
			}
			else
			{
				RightRotation(rt);
			}
		}
	}
	else
	{
		if (avl[rt].ls&&avl[rt].rs)
		{
			if (height(avl[rt].ls)>height(avl[rt].rs))
			{
				int k=Maximum(avl[rt].ls);
				avl[rt].val=avl[k].val;
				dele(avl[rt].ls,avl[k].val);
			}
			else
			{
				int k=Minimum(avl[rt].rs);
				avl[rt].val=avl[k].val;
				dele(avl[rt].rs,avl[k].val);
			}
		}
		else
		{
			rt=avl[rt].ls+avl[rt].rs;
		}
	}
	pushup(rt);
}
int kth(int rt,int k)
{
	if (avl[avl[rt].ls].size+avl[rt].cnt==k) return avl[rt].val;
	else if(k<=avl[avl[rt].ls].size) return kth(avl[rt].ls,k);
	else return kth(avl[rt].rs,k-avl[avl[rt].ls].size-avl[rt].cnt);
}
int Rank(int rt,int val)
{
	if (rt==0) return 1;
	if (avl[rt].val>=val) return Rank(avl[rt].ls,val);
	else return avl[avl[rt].ls].size+avl[rt].cnt+Rank(avl[rt].rs,val);
}
int Pre(int rt,int val)
{
	return kth(rt,Rank(rt,val)-1);
}
int suc(int rt,int val)
{
	return kth(rt,Rank(rt,val+1));
}
int main()
{
	int n;
	cin>>n;
	for (int i=1;i<=n;++i)
	{
		int opt,v;
		cin>>opt;
		if (opt==1)
		{
			cin>>v;
			insert(root,v);	
		}
		else if(opt==2)
		{
			cin>>v;
			dele(root,v);
		}
		else if(opt==3)
		{
			cin>>v;
			cout<<Rank(root,v)<<endl;
		}
		else if (opt==4)
		{
			cin>>v;
			cout<<kth(root,v)<<endl;
		}
		else if(opt==5)
		{
			cin>>v;
			cout<<Pre(root,v)<<endl;
		}
		else if(opt==6)
		{
			cin>>v;
			cout<<suc(root,v)<<endl;
		}
		else if(opt==7)
		{
			inorder(root);
			cout<<endl;
		}
		else if(opt==8)
		{
			preorder(root);
		}
		
	}
	/*
	inorder(root);
	cout<<endl;
	preorder(root);
	*/
}
/*
in 1 rightrotation
9
1 3
1 4
1 2
1 1
7
8
2 4
7
8

in 2 leftrotation
9
1 4
1 2
1 5
1 7
7
8
2 2
7
8

in 3
9
1 4
1 5
1 7
1 2
7
8
2 2
7
8

in 4
10
1 10
1 5
1 12
1 4
1 6
7
8
2 5
7
8

in 5
10
1 10
1 5
1 12
1 4
1 6
7
8
2 12
7
8

*/ 

  

标签:rt,rs,int,height,avl,P3369,ls,模板
来源: https://www.cnblogs.com/smghj/p/16127633.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有