1. 程式人生 > 其它 >二叉搜尋樹 陣列版參考程式碼

二叉搜尋樹 陣列版參考程式碼

資料結構定義

struct node{
	int data;//結點的內容 
	int left;//左子樹 
	int right;//右子樹 
	int cnt;
	int size; 
} Bst[100100];
queue<int> sq;
int root=0;
int tot=0;

更新子樹大小:等於左子樹+右子樹+自身大小

//更新樹的大小 
void update(int r)
{
	Bst[r].size=Bst[Bst[r].left].size+Bst[Bst[r].right].size+Bst[r].cnt;
}

插入

//插入x的值 
void insert(int &r,int x)
{
	if (r==0)
	{
		tot=sq.front();
		sq.pop();
		r=tot;
		Bst[tot].data=x;
		Bst[tot].left=0;
		Bst[tot].right=0; 
		Bst[tot].cnt=1;
		Bst[tot].size=1;
	}
	else
	{
		//Bst[r].size++;
		if(x>Bst[r].data)
		{
			insert(Bst[r].right,x);
		}
		else if(x<Bst[r].data) 
		{
			insert(Bst[r].left,x);
		}
		else
		{
			Bst[r].cnt++;Bst[r].size++;
		}
	}
	update(r); 
}

查詢指定值

int Search(int r,int val)
{
	if (r==0) return 0;
	if(Bst[r].data>val)
	{
		return Search(Bst[r].left,val);
	}
	else if(Bst[r].data==val)
	{
		return r;
	}
	else
	{
		return Search(Bst[r].right,val);
	}
}

查詢子樹的最小值

//查詢r子樹的最小值的結點編號
int findMin(int r)
{
	if (r==0)
	{
		return 0;	
	}
	else 
	{
		int ans=r;
		while(Bst[r].left!=0)
		{
			ans=Bst[r].left;
			r=Bst[r].left;
		}
		return ans;
	}
}

查詢子樹的最大值

//查詢r子樹的最大值的結點編號 
int findMax(int r)
{
	if (r==0)
	{
		return 0;	
	}
	else 
	{
		int ans=r;
		while(Bst[r].right!=0)
		{
			ans=Bst[r].right;
			r=Bst[r].right;
		}
		return ans;
	}
}

第k小值

//第k名的值 
int Kth(int r,int k)
{
	if(Bst[Bst[r].left].size>=k)
	{
		return Kth(Bst[r].left,k);
	} 
	else if (Bst[Bst[r].left].size+Bst[r].cnt>=k)
	{
		return Bst[r].data;
	} 
	else
	{
		return Kth(Bst[r].right,k-Bst[Bst[r].left].size-Bst[r].cnt);
	}
} 

查詢val的排名

//val的排名 
int Rank(int r,int val)
{
	int rank=0;
	while(r!=0)
	{
		if (Bst[r].data==val) return rank+Bst[Bst[r].left].size+1;
		if (Bst[r].data>val)
		{
			r=Bst[r].left;
		}
		else
		{
			rank+=Bst[Bst[r].left].size+Bst[r].cnt;
			r=Bst[r].right;
		}
	}
	return rank+1;
}

統計某個值的個數

int Count(int r,int val)
{
	if(r==0) return 0;
	if (Bst[r].data==val) return Bst[r].cnt;
	else if(Bst[r].data>val) return Count(Bst[r].left,val);
	else return Count(Bst[r].right,val); 
} 

查詢前驅

int Pre(int r,int val)
{
	int rk=Rank(r,val);
	return Kth(r,rk-1); 
}

查詢後繼

//找val的後繼 
int Sur(int r,int val)
{
	int rk=Rank(r,val);
	int ck=Count(r,val);
	return Kth(r,rk+ck);
}

刪除

//刪除演算法這個演算法不是最好可以優化 
void Delete(int &r,int val)
{
	if (r==0)
	{
		return ;	
	}
	else if(Bst[r].data==val)
	{
		if(Bst[r].left==0&&Bst[r].right==0)
		{
			sq.push(r);
			r=0;
			return ;
		}
		else if(Bst[r].left==0) //僅有右子樹 
		{
			int y,v;
			y=findMin(Bst[r].right);//右子樹查最小值
			v=Bst[y].data;
			Bst[r].data=v;
			Bst[r].cnt=Bst[y].cnt;
			Bst[r].size=Bst[y].size;
			Delete(Bst[r].right,v); 
			update(r);
		}
		else //僅有左子樹或兩個子樹 
		{
			int y,v;
			y=findMax(Bst[r].left);//左子樹查最大值
			v=Bst[y].data; 
			Bst[r].data=v;
			Bst[r].cnt=Bst[y].cnt;
			Bst[r].size=Bst[y].size;
			Delete(Bst[r].left,v); 
			update(r);
		}
	}
	else if(Bst[r].data>val)
	{
		Delete(Bst[r].left,val);
		update(r);
	}
	else
	{
		Delete(Bst[r].right,val);
		update(r);
	}
}
void DElete(int &r,int val)
{
	if (r==0) return ;
	if (Bst[r].data==val)
	{
		Bst[r].cnt--;
		Bst[r].size--;
		if (Bst[r].cnt==0)
		{
			Delete(r,val);
		}
	}
	else if(Bst[r].data>val)
	{
		DElete(Bst[r].left,val);
		update(r);
	}
	else
	{
		DElete(Bst[r].right,val);
		update(r);
	}
	update(r);
}