深入理解並查集

2021-10-06 02:10:53 字數 2404 閱讀 5733

並查集是一種樹形結構,它是由並查集演算法進行維護的。而並查集演算法(union-find-algorithm),顧名思義,它主要是由 「合併集合」 和 「查詢集合」,」合併集合「是將兩個連通的集合合併為乙個集合,」查詢集合「判斷某個節點的代表節點,也就是根節點。

圖的連通狀態如上圖所示,共分為三個集合,灰色、藍色、粉色。在乙個集合中任何兩個點都是連通的。

如何判斷兩個點是否在同一集合中呢,我們可以組織一種樹形結構,選擇乙個點當做根節點。要判斷兩個點是否在同一集合中,只需要分別對兩個點向上尋找,一直找到根節點。如果根節點相同,那麼連個點在同一集合中,兩個點是連通的。

不同集合之間一定不能連通。

並查集演算法是由乙個陣列和兩個函式構成,陣列 parents[ ] 其實就是樹形結構的儲存,記錄了每個點的前導點是什麼。函式 find 是查詢, union 是合併。

3.1 查詢演算法

int len =

1000

;int pre[len]

;int

find

(int c)

int i = c, j;

while

(i != r)

return r;

}

查詢過程如圖所示:

3.2 合併演算法

void

union

(int node1,

int node2)

}

3.3 路徑壓縮

這裡的壓縮演算法是為了提高查詢效率,直接令每乙個節點的父節點為根節點,那麼每次要查詢的時候只需要一次訪問即可找到根節點。

130. 被圍繞的區域

難度中等208

給定乙個二維的矩陣,包含'x''o'字母 o)。

找到所有被'x'圍繞的區域,並將這些區域裡所有的'o''x'填充。

示例:

x x x x

x o o x

x x o x

x o x x

執行你的函式後,矩陣變為:

x x x x

x x x x

x x x x

x o x x

解釋:被圍繞的區間不會存在於邊界上,換句話說,任何邊界上的'o'都不會被填充為'x'。 任何不在邊界上,或不與邊界上的'o'相連的'o'最終都會被填充為'x'。如果兩個元素在水平或垂直方向相鄰,則稱它們是「相連」的。

並查集:

class

unionfind

}public

void

union

(int node1,

int node2)

}public

intfind

(int node)

return node;

}boolean

isconnect

(int node1,

int node2)

}

將邊界的 o 和 內部的 o 分成兩個集合,然後對內部的 o 進行替換為 xx

public

class

solution

else

if(j-

1>=

0&& board[i]

[j-1]==

'o')

if(i +

1<= rows -

1&& board[i+1]

[j]==

'o')

if(j+

1<= cols -

1&& board[i]

[j+1]==

'o')}}

}}for(

int i =

0; i < rows; i++)}

}}public

intgetindex

(int i,

int j)

}

並查集理解

作用 連通分量的查詢與合併 理解 1.將連通分量看成乙個集合,該集合包含了連通分量的所有點。連同方式無關緊要,只有屬於和不屬於與這個集合的區別。2.每個集合都可看成一棵樹,這個集合的標誌 這棵樹的標誌 就是這棵樹的根。3.如果把節點x的父親節點儲存在pre x 中,那麼再從pre x 找它的父親節點...

並查集理解

學了這麼久的資料結構了,還是有好些演算法並沒弄清楚,搞得有些筆試題都是沒有思路,今天就講講並查集。感覺這東西吧,就是分圈子,乙個人自成乙個圈子,若分屬於兩個不同圈子的人在某時刻成了好朋友,那這兩個圈子就合併成了乙個圈子,最終在題目中形成多個圈子進行分析。判斷兩個人是不是乙個圈子要不停的找朋友驗證,這...

並查集的理解

並查集的模板,不理解也要背下來 include 萬能標頭檔案 using namespace std int par 100000 ran 10000 個數與深度 int n,m void init int n 初始化 當不需要返回值的時候,函式的型別標void。其實這個也是會返回乙個值,好像是呼叫...