並查集講解

2021-09-26 09:54:05 字數 1539 閱讀 6130

所謂並查集,實際上可以認為是對集合的合併與查詢,所以下面從集合開始講解。

假設有集合a:1 2 3 4 5,集合b:6 7 8 9 0;假設此時有乙個條件導致a中的隨便乙個數與b中的隨便乙個數在乙個集合內,那麼很顯然ab將會合併成乙個更大的集合。

接下來考慮演算法:

對乙個陣列f[50]來說,先對其進行初始化,即:

for(int i=0;i<50;i++)

f[i]=i;

f[i]的含義為f[i]與i在乙個集合內。由於此時經過初始化後,f[i]即為i本身,意思是i與自己在乙個集合內。

接下來考慮如何將兩個集合合併到同乙個集合內。

假設有乙個集合a:1 2 3 4 集合b:5 6,那麼在計算機中他們應該是以下面的形式表示的(表示形式不唯一,下面只是很多情況中的一種)

圖中的含義為f[4]=2,f[2]=1,f[3]=1;f[6]=5,之所以可以這樣表示為兩個集合,是因為從下往上查詢時,同集合的最終結果一定是相同的,所以如果想要將集合b合併到集合a中,只需要讓集合b最上面的元素連到集合a中的任意乙個元素上即可,如以下

這樣的話,由於6最考上的數變成了三,與其他的相同,所以a與b就等同於合併成了同乙個集合。

下面給出查詢的**

int find(int x)

return x;

}

這個是合併的**

void unionf(int x,int y)

}

讀者應該考慮到,如果在通過呼叫find()函式時,由於可能因為while迴圈執行次數過多,導致超時的問題,這種情況下,應該優化查詢時的**,下面給出為什麼可以優化以及**

還用之前的圖,假設要呼叫find()函式,查詢6的根節點,此時會在迴圈中查詢5 3 1 的根節點,最後返回1,這也就意味著,不僅僅6的根節點是1,其他過程中的幾個的根節點都是1,於是可以在求得根節點後,先不著急輸出,而是再次迴圈一次,把路徑中的根節點全部換成1,這樣以後再次查詢其中某個節點的根結點時,就再也不需要進入迴圈了。

優化**如下:

int find(int x)

//迴圈結束後x即為根

while(y!=f[y])

return x;

}

經過這樣的操作後,原圖會變成這種情形

顯然下一次再查詢時所需要的時間就會大幅度降低了。

其實查詢還有遞迴演算法,而且更加簡單容易理解一點,相信大家只要理解了上面的內容這個一看就懂,就不再講述了:

int find(int x)

並查集講解

什麼是並查集 並查集是一種資料結構,用來快速查詢集合元素之間是否有關係,是否有關係判斷標準是是否有相同的根節點 舉乙個恰當的例子,要判斷圖譜中的兩個元素是否有關係,如果使用常規的查詢方法,時間複雜度比較大,使用並查集就是用來優化這種情況,使得判斷兩個元素是否有關聯可以達到o 1 普通查詢思路 按照上...

並查集專題講解

並查集是一種樹型的資料結構,用於處理一些不相交集合的合併及查詢問題。例如 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,...