在計算機科學中,並查集是一種樹型的數據結構,其保持着用於處理一些不相交集合(Disjoint Sets)的合併及查詢問題。有一個聯合-查找算法(union-find algorithm)定義了兩個操作用於此數據結構:
Find:確定元素屬於哪一個子集。它可以被用來確定兩個元素是否屬於同一子集。
Union:將兩個子集合併成同一個集合。
因爲它支持這兩種操作,一個不相交集也常被稱爲聯合-查找數據結構(union-find data structure)或合併-查找集合(merge-find set)。
爲了更加精確的定義這些方法,需要定義如何表示集合。一種常用的策略是爲每個集合選定一個固定的元素,稱爲代表,以表示整個集合。接着。Find(x)返回x所屬集合的代表,而Union使用兩個集合的代表作爲參數。(取自維基百科)
開始時的狀態:
(摘自數據結構與算法分析 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; }