並查集 知識點

2021-07-15 23:23:45 字數 1429 閱讀 4559

並查集學習:l

並查集:(

union-find sets)

一種簡單的用途廣泛的集合. 並查集是若干個不相交集合,能夠實現較快的合併和判斷元素所在集合的操作,應用很多,如其求無向圖的連通分量個數等。最完美的應用當屬:實現kruskar演算法求最小生成樹。 l

並查集的精髓(即它的三種操作,結合實現**模板進行理解): 1

、make_set(x) 把每乙個元素初始化為乙個集合

初始化後每乙個元素的

父親節點

是它本身,每乙個元素的

祖先節點

也是它本身(也可以根據情況而變)。

2、find_set(x) 查詢乙個元素所在的集合

查詢乙個元素所在的集合,其精髓是

找到這個

元素所在集合的

祖先!這個才是並查集判斷和合併的最終依據。

判斷兩個元素是否屬於同一集合

,只要看他們所在集合的祖先是否相同即可

。合併兩個集合,也是使乙個集合的祖先成為另乙個集合的祖先,具體見示意圖 3

、union(x,y) 合併x,y所在的兩個集合

合併兩個不相交集合操作很簡單:

利用find_set找到其中兩個集合的祖先,

將乙個集合的祖先指向另乙個集合的祖先

。如圖

l並查集的優化 1

、find_set(x)時 路徑壓縮

尋找祖先時我們一般採用遞迴查詢,

但是當元素很多亦或是整棵樹變為一條鏈時,每次find_set(x)都是o(n)的複雜度,

有沒有辦法減小這個複雜度呢?

答案是肯定的,這就是路徑壓縮,即

當我們經過"遞推"找到祖先節點後,"回溯"的時候順便將它的子孫節點都直接指向祖先,

這樣以後再次find_set(x)時複雜度就變成o(1)了,如下圖所示;可見,路徑壓縮方便了以後的查詢。 2

、union(x,y)時 按秩合併

即合併的時候將元素少的集合合併到元素多的集合中,這樣合併之後樹的高度會相對較小。

路徑壓縮就是把所有節點的父節點都變成這個集合的根節點,如上圖,d為根節點,把所有節點的父節點都變成d;

適用條件:節點很多的時候,時間複雜度高,需要用路徑壓縮;但是需要用到節點的父節點的時候就不能用路徑壓縮;

路徑壓縮**:

1  迴圈;

int find(int x)

return r;

}

2 遞迴;

int find(int x)

並查集知識

其實並查集顧名思義就是有 合併集合 和 查詢集合 兩種操作的關於資料結構的一種演算法。並查集演算法不支援分割乙個集合。用集合中的某個元素來代表這個集合,該元素稱為集合的代表元。乙個集合內的所有元素組織成以代表元為根的樹形結構。對於每乙個元素 parent x 指向x在樹形結構上的父親節點。如果x是根...

任意點 並查集

傳送門 方法就是在同一行的是乙個集合,在同一列的也是乙個集合,先存再乙個乙個列舉即可。這裡主要就是要注意,當所有的點都已經全部連線完畢之後,編號為i的點的祖先並不是fa i 而是fin i 因為最後還要進行一次預處理,將所有的點都重新整合一遍 防止出現類似於,1,2,3,4,5是乙個集合,那麼可能f...

並查集知識總結

1.非路徑壓縮 遞迴版 int64 findroot int64 x 非遞迴版 int64 findroot int64 x 查詢x的根節點 2.帶路徑壓縮 遞迴版 int64 findroot int64 x 找x的根節點 非遞迴版 int64 findroot int64 x return r ...