資料結構之並查集

2021-06-08 08:29:23 字數 1158 閱讀 6120

並查集:(union-find sets)是一種簡單的用途廣泛的集合. 並查集是若干個不相交集合,能夠實現較快的合併和判斷元素所在集合的操作,應用很多,如其求無向圖的連通分量個數、最小公共祖先、帶限制的作業排序,還有最完美的應用:實現kruskar演算法求最小生成樹。其實,這一部分《演算法導論》講的很精煉。

一般採取樹形結構來儲存並查集,在合併操作時可以利用樹的節點數(加權規則)或者利用乙個rank陣列來儲存集合的深度下界--啟發式函式,在查詢操作時進行路徑壓縮使後續的查詢操作加速。這樣優化實現的並查集,空間複雜度為o(n),建立乙個集合的時間複雜度為o(1),n次合併m查詢的時間複雜度為o(m alpha(n)),這裡alpha是ackerman函式的某個反函式,在很大的範圍內這個函式的值可以看成是不大於4的,所以並查集的操作可以看作是線性的。

它支援以下三種操作:

-union (root1, root2) //合併操作;把子集合root2和子集合root1合併.要求:root1和 root2互不相交,否則不執行操作.

-find (x) //搜尋操作;搜尋元素x所在的集合,並返回該集合的名字--根節點.

-ufsets (s) //建構函式。將並查集中s個元素初始化為s個只有乙個單元素的子集合.

-對於並查集來說,每個集合用一棵樹表示。

-集合中每個元素的元素名分別存放在樹的結點中,此外,樹的每乙個結點還有乙個指向其雙親結點的指標。   

-為簡化討論,忽略實際的集合名,僅用表示集合的樹的根來標識集合。

下面是我的實現:

static int max=100010;

static int parent=new int[max];

static int rank=new int[max];

static int pre=new int [max];

void init()

{ for(int i=0;irank[fb])

parent[fb]=fa;

else if(rank[fa]

資料結構之並查集

覺得很不錯的參考資料引用一下 陣列實現 合併操作代價高,可達o n 2 鍊錶實現 樹結構實現 查詢與合併的平均時間複雜度為o log 2 n 與樹的深度有關,優化 降低時間複雜度 按秩合併 若h b h b,則將b樹作為a樹的子樹。帶路徑壓縮的查詢演算法 改變結點所指方向以減小深度,查詢路徑時 走兩...

資料結構之並查集

1.將兩個集合合併。2.詢問兩個元素是否在乙個集合當中。複雜度近乎o 1 基本原理 每個集合用一棵樹來表示。樹根的編號就是整個集合的編號。每個節點儲存它的父節點,p x 表示x的父節點。問題1 如何判斷樹根 if p x x 問題2 如何求x的集合編號 while p x x x p x 問題3 如...

資料結構之並查集

並查集是一種用來管理元素分組情況的資料結構。並查集可以高效地進行如下操作。不過需要注意並查集雖然可以進行合併操作,但是卻無法進行分割操作。n個城市中 編號1 n 有一些城市間會有無向的通路。現在小明想從a城市到b城市,判斷是否能實現?即a和b是否有直接或間接的道路連通起來。如有4個城市,其中1和2有...