並查集(union/find)

在計算機科學中,並查集是一種樹型的數據結構,其保持着用於處理一些不相交集合(Disjoint Sets)的合併及查詢問題。有一個聯合-查找算法union-find algorithm)定義了兩個操作用於此數據結構:

  • Find:確定元素屬於哪一個子集。它可以被用來確定兩個元素是否屬於同一子集。

  • Union:將兩個子集合併成同一個集合。

因爲它支持這兩種操作,一個不相交集也常被稱爲聯合-查找數據結構(union-find data structure)或合併-查找集合(merge-find set)。

爲了更加精確的定義這些方法,需要定義如何表示集合。一種常用的策略是爲每個集合選定一個固定的元素,稱爲代表,以表示整個集合。接着。Find(x)返回x所屬集合的代表,而Union使用兩個集合的代表作爲參數。(取自維基百科)

開始時的狀態:

wKiom1ajPoaAvXHdAAAou7Rd7dY663.png

(摘自數據結構與算法分析 Java語言描述第二版)

即定義:

for(int i=0;i<n;i++)
    id[i]=-1;

以下爲具體實現:

class unionfind
{
	private int count;
	private int[] id;
	public union(int n)
	{
		count=n;
		id=new id[n];
		for(int i=0;i<n;i++)
			id[]=-1;
	}
	public int count()
	{
		return count;
	}
	public boolean connected(int p,int q)
	{
		return find(p)==find(q);
	}
	private int find(int n)
	{
		while(p!=id[p])
			p=id[p];
		return p;
	}
	public void union(int p.int q)  //按大小union
	{
		int proot=find(p);
		int qroot=find(q);
		if(proot==qroot)
			return;
		id[proot]=qroot;
			count--;
	}
}

優化方式 按高度union

for(inti=0;i<n;i++)
	sz[i]=1;
public void union(int p,int q)  //按高度union
{
	int proot=find(p);
	int qroot=find(q);
	if (sz[proot<sz[qroot]]) 
	{
		id[proot]=qroot;
		sz[qroot]+=sz[proot];	
	}
	else
	{
		id[qroot]=proot;
		sz[proot]+=sz[qroot];
		count--;
	}
}

路徑壓縮

private int find(int n)    //路徑壓縮
{
	while(n!=id[n])
		n=id[id[n]];
	return n;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章