什麼是並查集
並查集是一種資料結構,用來快速查詢集合元素之間是否有關係,是否有關係判斷標準是是否有相同的根節點
舉乙個恰當的例子,要判斷圖譜中的兩個元素是否有關係,如果使用常規的查詢方法,時間複雜度比較大,使用並查集就是用來優化這種情況,使得判斷兩個元素是否有關聯可以達到o(1)
普通查詢思路
按照上圖,要判斷11和4是否有關係,我們可以一直向上追溯父親節點,11的上層是9,9的上層節點是0,那麼11的祖父節點就是0。同理,追溯4的祖父節點是0,那麼這兩個節點的祖父節點都是0,則兩個節點有關係
知道了思路,抽象出**就很簡單了,現在要解決的有兩個問題,使用非遞迴,從下往上進行追溯,什麼時候是截止條件呢,可以讓0號節點的父節點指向自己。第二個問題就是如何儲存這樣乙個結構,由於每個節點只需要用到父節點,可以使用map來進行儲存,**如下:
//找a的祖父節點
int father = map.
get(a)
;while
(father != map.
get(father)
)
o(1)優化
按照上面的思路一級一級的追溯,很明顯時間複雜度是o(n),如何進行優化呢
舉個例子,當查詢過一遍4的祖父節點是0的時候,我們就可以直接更新4的父節點是0,後續再使用到4的時候,就不會做重新勞動了,我們可以繼續思考,既然用到4了,我們可以直接將4開始往上所有的路徑節點都直接更新
所以,整個思路分為兩步,第一步還是先找到頂級根節點,第二步從當前節點開始往上,依次更新父節點
//找a的祖父節點
int father = map.
get(a)
;while
(father != map.
get(father)
)//從當前節點往上更新父節點
int temp =-1
;int fa = map.
get(a)
;while
(fa != map.
get(fa)
)
資料結構
根據上面的思路,就可以整理出來該資料結構
class
unionfind
//初始化所有節點,每個節點的父節點都指向自己
public
void
find0()
public
intfind
(int num)
//從當前節點往上更新父節點
int temp =-1
;int fa = map.
get(num)
;while
(fa != map.
get(fa)
)return father;
}//合併
public
void
union
(int a,
int b)
}}
並查集講解
所謂並查集,實際上可以認為是對集合的合併與查詢,所以下面從集合開始講解。假設有集合a 1 2 3 4 5,集合b 6 7 8 9 0 假設此時有乙個條件導致a中的隨便乙個數與b中的隨便乙個數在乙個集合內,那麼很顯然ab將會合併成乙個更大的集合。接下來考慮演算法 對乙個陣列f 50 來說,先對其進行初...
並查集專題講解
並查集是一種樹型的資料結構,用於處理一些不相交集合的合併及查詢問題。例如 1,合併兩個集合,複雜度是o 1 2,查詢乙個元素在哪個集合裡面,複雜度o 1 3,查詢兩個元素是否在同乙個集合裡面。1,初始化 每個結點的父親結點首先設為它本身。void init 2,路徑壓縮 解決特殊情況下的樹的層次深而...
C 並查集 例題講解
一 基本性質 1.在基於並查集的基礎上增加記錄陣列 rank,表示i與其同集合根節點的關係 二 例題講解 2.1 食物鏈 poj 1182 vjudge題目鏈結 題意 動物王國中有三類動物a,b,c,這三類動物的食物鏈構成了有趣的環形。a b吃c,c吃a。現有n個動物,以1 n編號。每個動物都是a,...