做了幾道並查集的題,在這裡做乙個小小的總結,以表達我對這個精簡的資料結構的淺顯的理解。。。
先說說用途:
1、並查集,顧名思義分為並和查。
並:即:將兩個完全不相交的集合合併為乙個集合。
查:查詢某個元素屬於哪乙個集合,一般用來判斷兩個元素是否屬於同一集合。
2、目前我所接觸到的它的實際用途:
(1)、求解最小生成樹(克魯斯卡爾演算法)
(2)、判斷圖是否連通或是否有環
(3)、確定無向圖的連通子圖個數
(4)、確定某一集合或者團體有多少元素(或個體)。
接下來就說說並查集的三種操作(三個函式):
1、make_set(x):把每乙個元素初始化為乙個集合。
初始化後每乙個元素的父親節點是它本身,每乙個元素的祖先節點也是它本身(也可以根據情況而變)。
2、getparent(x) :查詢乙個元素所在的集合。
其精髓是找到這個元素所在集合的祖先!這個才是並查集判斷和合併的最終依據。判斷兩個元素是否屬於同一集合,只要看他們所在集合的祖先是否相同即可。
3、merge(x,y):合併x,y所在的兩個集合
合併兩個不相交集合操作很簡單:
利用getparent函式找到這兩個集合的祖先,將乙個集合的祖先指向另乙個集合的祖先。
對於並查集的優化,乙個是路徑壓縮,乙個是按秩合併,這也是這個資料結構的精髓所在和最為優美的地方。
直接看**:
int
parent[max]; /* father[x]表示x的父節點*/
int rank[max]; /* rank[x]表示x的秩*/
// 初始化集合
void make_set(int x)
// 查詢x元素所在的集合,回溯時壓縮路徑
int getparent(int a)
/* 按秩合併x,y所在的集合
下面的那個if else結構不是絕對的,具體根據情況變化
但是,宗旨是不變的即,按秩合併,實時更新秩。
*/void merge(int x, int y)
else
parent[x] = y;
}}
一 並查集 Union Find Set)
如果 給出各個元素之間的聯絡,要求將這些元素分成幾個集合,每個集合中的元素直接或間接有聯絡。在這類問題中主要涉及的是對集合的合併和查詢,因此將這種集合稱為並查集。鍊錶被普通用來計算並查集.表中的每個元素設兩個指標 乙個指向同一集合中的下乙個元素 另乙個指向表首元素。鏈結構的並查集 採用鏈式儲存結構,...
並查集 Union Find Set 的學習
什麼是並查集?乙個實現了合併與查詢集合的資料結構。可以解決動態連通性一類的問題。那什麼是動態連通性問題?給出一系列的物件時,讓其支援下列操作 這裡以整數表示物件,有0 9共十個整數,當給出乙個整數對 a,b 時表示將整數a和b相連 如果a b不相連 如下圖所示 隨著整數對的輸入,十個整數的連通性會發...
並查集 並查集
本文參考了 挑戰程式設計競賽 和jennica的github題解 陣列版 int parent max n int rank max n void init int n int find int x else void union int x,int y else 結構體版 struct node ...