並查集詳解

2021-07-25 02:32:53 字數 1572 閱讀 3763

其實並查集顧名思義就是有「合併集合」和「查詢集合」兩種操作的關於資料結構的一種演算法。

並查集演算法不支援分割乙個集合。

用集合中的某個元素來代表這個集合,該元素稱為集合的代表元

乙個集合內的所有元素組織成以代表元為根的樹形結構。

對於每乙個元素 parent[x]指向x在樹形結構上的父親節點。如果x是根節點,則令parent[x] = x。

對於查詢操作,假設需要確定x所在的的集合,也就是確定集合的代表元。可以沿著parent[x]不斷在樹形結構中向上移動,直到到達根節點。

判斷兩個元素是否屬於同一集合,只需要看他們的代表元是否相同即可。
為了加快查詢速度,查詢時將x到根節點路徑上的所有點的parent設為根節點,該優化方法稱為壓縮路徑。

使用該優化後,平均複雜度可視為ackerman函式的反函式,實際應用中可粗略認為其是乙個常數。

1、維護無向圖的連通性。支援判斷兩個點是否在同一連通塊內,和判斷增加一條邊是否會產生環。(不理解)

2、用在求解最小生成樹的kruskal演算法裡。

《acm國際大學生程式設計競賽 知識與入門 俞勇主編》

一般來說,乙個並查集一三個操作。

有的人是建立乙個結構體把集合表示出來,如:

#define max 10000

struct node

node[max];

有的人則是弄很多相同大小的陣列,如:

int

set[max];//集合index的類別,或者用parent表示

int rank[max];//集合index的層次,通常初始化為0

int data[max];//集合index的資料型別

//初始化集合

void

make_set

(int i)

一般來說,題目簡單用陣列,題目複雜用結構體,因為結構體有條理,陣列可以少打幾個字。
/**

*查詢集合i(乙個元素是乙個集合)的源頭(遞迴實現)。

如果集合i的父親是自己,說明自己就是源頭,返回自己的標號;

否則查詢集合i的父親的源頭。

**/int

get_parent

(int x)

陣列的話就是:

//查詢集合i(乙個元素是乙個集合)的源頭(遞迴實現)

intfind_set

(int i)

這就是所謂並查集的並了。至於怎麼知道兩個集合是可以合併的,那就是題目的條件了。先看**:

void

union

(int a,int b)

}

再給出陣列顯示的合併函式:

void

union

(int i,int j)

}

詳解並查集

並查集主要用來求解不相交集合的問題,主要針對於合併和查詢兩種演算法。並查集的實現主要包含了三個部分 並查集的初始化是對單個資料建立了乙個單獨的集合,每個集合應該包含以下兩個資料 由以上兩個資料,一般的並查集的結構一般有兩種表示形式 結構體構造如下 define max 50 struct node ...

並查集詳解

看大佬的形象解釋 並查集 按我現在對這個的理解 就是給你一堆數,然後給你兩個兩個數的關係,然後關係的傳遞性 連帶性 這些數就都有了關係 有關係的數組成乙個陣列,然後輸出這個一維陣列,裡面有幾個沒關係的陣列 應該怎麼做呢?第一種解釋是 每給兩個數就把乙個數當成祖宗,把另乙個數當成孩子,然後給了孩子和另...

並查集詳解

並查集是一種樹型的高階資料結構,主要用於處理不相交集合的合併及查詢問題。它在電腦科學中有著廣泛的應用,例如求解最小生成樹 親戚關係的判定 確定無向圖的連通子圖個數 最小公共祖先問題等,都要用到並查集。集合是數學中最基本的構造之一,將一組滿足某種性質的物件放在一起就形成了集合。集合中包含的物件稱為集合...