1. 程式人生 > >手寫一個節點大小平衡樹(SBT)模板,留著用

手寫一個節點大小平衡樹(SBT)模板,留著用

看了一下午,感覺有了些瞭解,應該沒有錯,有錯希望斧正,感謝

#include<stdio.h>
#include<string.h>
struct s
{
	int key,left,right,size;
}tree[10010];
int top;
void left_rot(int &x)// 左旋
{
	int y=tree[x].right;
	tree[x].right=tree[y].left;
	tree[y].left=x;
	tree[y].size=tree[x].size;
	tree[x].size=tree[tree[x].left].size+tree[tree[x].right].size+1;
	x=y;
}
void right_rot(int &x)//右旋
{
	int y=tree[x].left;
	tree[x].left=tree[y].right;
	tree[y].right=x;
	tree[y].size=tree[x].size;
	tree[x].size=tree[tree[x].left].size+tree[tree[x].right].size+1;
	x=y;
}
void maintain(int &x,bool flag)//維護SBT狀態
{
	if(flag==false)//左邊
	{
		if(tree[tree[tree[x].left].left].size>tree[tree[x].right].size)//左孩子的左孩子大於右孩子
			right_rot(x);
		else
			if(tree[tree[tree[x].left].right].size>tree[tree[x].right].size)//左孩子的右孩子大於右孩子
			{
				left_rot(tree[x].left);
				right_rot(x);	
			}
			else
				return;
	}
	else//右邊
	{
		if(tree[tree[tree[x].right].right].size>tree[tree[x].left].size)//右孩子的右孩子大於左孩子
			left_rot(x);
		else
			if(tree[tree[tree[x].right].left].size>tree[tree[x].left].size)//右孩子的左孩子大於左孩子
			{
				right_rot(tree[x].right);
				left_rot(x);
			}
			else
				return;
	}
	maintain(tree[x].left,false);
	maintain(tree[x].right,true);
	maintain(x,true);
	maintain(x,false);
}
void insert(int &x,int key)//插入
{
	if(x==0)
	{
		x=++top;
		tree[x].left=0;
		tree[x].right=0;
		tree[x].size=1;
		tree[x].key=key;
	}
	else
	{
		tree[x].size++;
		if(key<tree[x].key)
			insert(tree[x].left,key);
		else
			insert(tree[x].right,key);//相同元素可插右子樹
		maintain(x,key>=tree[x].key);
	}
}
int remove(int &x,int key)//利用後繼刪除
{
	tree[x].size--;
	if(key>tree[x].key)
		remove(tree[x].right,key);
	else
		if(key<tree[x].key)
			remove(tree[x].left,key);
		else
			if(tree[x].left!=0&&tree[x].right==0)//有左子樹,無右子樹
			{
				int temp=x;
				x=tree[x].left;
				return temp;
			}
			else
				if(!tree[x].left&&tree[x].right!=0)//有右子樹,無左子樹
				{
					int temp=x;
					x=tree[x].right;
					return temp;
				}
				else
					if(!tree[x].left&&!tree[x].right)//無左右子樹
					{
						int temp=x;
						x=0;
						return temp;
					}
					else//左右子樹都有
					{
						int temp=tree[x].right;
						while(tree[temp].left)
							temp=tree[temp].left;
						tree[x].key=tree[temp].key;
						remove(tree[x].right,tree[temp].key);
					}
}
int getmin(int x)//求最小值
{
	while(tree[x].left)
		x=tree[x].left;
	return tree[x].key;
}
int getmax(int x)//求最大值
{
	while(tree[x].right)
		x=tree[x].right;
	return tree[x].key;
}
int pred(int &x,int y,int key)//前驅,y初始前驅,從0開始, 最終要的是返回值的key值
{
	if(x==0)
		return y;
	if(key>tree[x].key)
		return pred(tree[x].right,x,key);
	else
		return pred(tree[x].left,y,key);
}
int succ(int &x,int y,int key)//後繼,同上
{
	if(x==0)
		return y;
	if(key<tree[x].key)
		return succ(tree[x].left,x,key);
	else
		return succ(tree[x].right,y,key);
}
int select(int &x,int k)//選第k小的數
{
	int r=tree[tree[x].left].size+1;
	if(r==k)
		return tree[x].key;
	else
		if(r<k)
			return select(tree[x].right,k-r);
		else
			return select(tree[x].left,k);
}
int rank(int &x,int key)//key排第幾
{
	if(key<tree[x].key)
	{
		return rank(tree[x].left,key);
	}
	else
		if(key>tree[x].key)
			return rank(tree[x].right,key)+tree[tree[x].left].size+1;
		else
			return tree[tree[x].left].size+1;
}
void order(int &x)
{
	if(x==0)
		return;
	order(tree[x].left);
	printf("%d\n",tree[x].key);
	order(tree[x].right);
}
int main()
{
	top=0;
}