資料結構之並查集

2021-10-06 18:39:44 字數 2982 閱讀 5396

我是自動化專業的應屆研究生,最終拿到了tplink、華為、vivo等公司的ssp的offer,分享自己學習過的計算機基礎知識(c語言+作業系統+計算機網路+linux)以及資料結構與演算法的相關知識,保證看完讓你有所成長。

歡迎關注我,學習資料免費分享給你哦!還有其他超多學習資源,都是我自己學習過的,經過過濾之後的資源,免去你還在因為擁有大量資源不知如何入手的糾結,讓你體系化學習。

並查集是一種用來表示集合的資料結構,表示某個元素是否是集合中的乙份子,只要有兩種操作,一種是查詢,找出兩個元素a和b是否為同乙個集合之中;另一種操作就是合併操作,將兩個不在乙個集合的元素a和b合併到乙個集合中。

為了能夠實現這種資料結構,可以使用樹,通過判斷兩個元素a和b的樹根是否相同,就可以判斷是否是在乙個集合之中,通過將b所在的樹合併到a所在的樹就可以完成兩個元素合併到乙個集合之中。

我們可以用陣列來表示這種樹的結構,比如以s為陣列名,然後s[a]和s[b]的值就是父節點,當值為-1或者超出陣列範圍的值用來作為樹的根。

初始化為下圖所示的集合,每個元素都是自己乙個集合。

假如把3和4合併到乙個集合,只需把s[4]=3,相當於把4作為了3的乙個子節點。

那麼查詢i節點的所在集合的根的過程就是尋找s[i]是否等於-1,如果等於-1,說明就是i所在集合的根,如果s[i]!=-1,而是等於a,那麼就繼續尋找s[a]的值,直到等於-1.

int

find

(int

*a,int d)

else

}

對於合併的操作,有兩種方式,一種是按照樹的大小,也就是這個集合中有多少個元素來判斷將a集合合併到b集合還是b集合合併到a集合中。這個時候集合的根節點的負數是有意義的,絕對值表示的是集合中元素的個數。所以**如下

void

myunion

(int

*a,int i,

int j)

else

}

先利用find函式找到要合併的兩個元素所在集合的根節點,然後判斷根節點的值,如果root1的值小於root2,說明root1的集合元素數量大於root2,因為是負數表示,絕對值大的反而小。比如有下面的集合:

乙個集合根節點為1只有乙個元素此時a[root1]=-1,另乙個集合根節點為3,有三個元素,此時a[root2]=-3,a[root2]

另一種是按照樹的高度來合併,此時根節點的負值表示的樹的高度,對於樹的高度來說,只有將相等高度的兩個樹合併在一起,樹的高度才會改變,否則將小的樹合併在高的樹上,是不會改變樹的高的的。

比如上圖所示的兩個樹,假設左邊的1的高度是-1,即s[1]=-1,右邊的樹的高度是2,s[3]=-2.此時把兩個集合合併在一起,那麼因為集合3的高度大於集合1的高度,所以把1合併到3上,即s[1]=3.

此時集合3的高度還是2,所以s[3]的值不需要改變。

如果是兩個集合s[1]=-1,s[3]=-1,將這兩個集合合併,假設將集合1合併到集合3上,那麼此時集合3的高度就是2了,此時s[1]=3,s[3]=-2.

**如下:

void myunion(int *a,int i,int j)

else

}

在查詢的過程中,遞迴的查詢,直到找到根節點,如果我們在查詢的過程中,能夠將父節點的節點不是根節點的節點更新為根節點,不就可以將查詢的路徑簡化了嘛。比如上圖所示,在查詢節點11(s[11]=9)時的根節點,找到了為1,此時將s[11]=1,下一次查詢時就可以直接找到根節點的值了。

這樣逐漸可以將樹的高度降低,查詢起來更加高效。**如下:

int find(int *a,int d)

else

}

練習的習題:file transfer

#include#includeint find(int *data,int x)

else }

void uion(int *data,int begin,int end)

else

else

data[root1]-=data[root2];

data[root2]=root1;

} }}void check_connection(int *data,int n)

else }

void set_connection(int *data,int n)

void check_components(int *data,int n)

} if(uion_connect==1)

else }

int main()

do}while(ch!='s');

return 0;

}

資料結構之並查集

並查集 union find sets 是一種簡單的用途廣泛的集合.並查集是若干個不相交集合,能夠實現較快的合併和判斷元素所在集合的操作,應用很多,如其求無向圖的連通分量個數 最小公共祖先 帶限制的作業排序,還有最完美的應用 實現kruskar演算法求最小生成樹。其實,這一部分 演算法導論 講的很精...

資料結構之並查集

覺得很不錯的參考資料引用一下 陣列實現 合併操作代價高,可達o n 2 鍊錶實現 樹結構實現 查詢與合併的平均時間複雜度為o log 2 n 與樹的深度有關,優化 降低時間複雜度 按秩合併 若h b h b,則將b樹作為a樹的子樹。帶路徑壓縮的查詢演算法 改變結點所指方向以減小深度,查詢路徑時 走兩...

資料結構之並查集

1.將兩個集合合併。2.詢問兩個元素是否在乙個集合當中。複雜度近乎o 1 基本原理 每個集合用一棵樹來表示。樹根的編號就是整個集合的編號。每個節點儲存它的父節點,p x 表示x的父節點。問題1 如何判斷樹根 if p x x 問題2 如何求x的集合編號 while p x x x p x 問題3 如...