並查集(disjoint set)用來判斷已有的資料是否構成環。
在構造圖的最小生成樹(minimum spanning tree)時,如果採用 kruskal 演算法,每次新增最短路徑前,需要先用並查集來判斷一下這個路徑是否會構成環。
遍歷圖的每一條邊,按照下面的原則將對應的兩個頂點新增到集合中:
為了**上的統一性,可以在開始前,把所有頂點都看成只有乙個元素的集合,然後就是不停的合併集合。
集合可以用樹的雙親表示法來表示,只需要額外建立乙個陣列即可。為了簡化合併操作,可以每次都只操作兩顆樹的根結點。
int parent[n]
;// 查詢樹的根結點
intfindroot
(int parent,
int key)
return root;
}// 合併樹
intunionvertex
(int parent,
int x,
int y)
// 否則,合併樹,這裡直接把左樹作為右樹的子樹,可能會導致不平衡
parent[lroot]
= rroot;
}
為了在每次合併時,盡可能保證樹的平衡,再建立乙個陣列儲存樹的高度,合併時將高度低的樹作為子樹即可。
#include
void
init
(int parent,
int height,
int count)
}int
findroot
(int parent,
int key)
return root;
}int
unionvertex
(int parent,
int height,
int x,
int y)
// parent[lroot] = rroot;
if(height[lroot]
< height[rroot]
)else
if(height[rroot]
< height[lroot]
)else
return1;
}int
main
(void),
,,,}
;int parent[edgecount]
;int height[edgecount]
;init
(parent, height, edgecount)
;for
(i =
0; i < vertexcount; i++)}
printf
("no find cycle!\n");
for(i =
0; i < vertexcount; i++
)for
(i =
0; i < vertexcount; i++
)return0;
}
執行結果:
no find cycle!
0's parent is:
11's parent is:
42's parent is:
43's parent is:
44's parent is:-1
0's height is:
01's height is:
12's height is:
03's height is:
04's height is:
2
資料結構與演算法之並查集
並查集結構可以用於 1 檢查兩個元素是否屬於同乙個集合 比如對於圖1這個例子來說,如果我們想要檢查節點d和節點e是否屬於同乙個集合,可以這樣操作 d節點往上找其父節點,一直往上找,直到某個節點的父節點是其本身,此時停止 找到了節點a e節點也按照相同的步驟往上找其父節點,找到節點a 如果這兩個節點往...
資料結構與演算法之並查集
並查集 union find 是一種高效的資料結構,主要的操作有 為方便敘述,把所有元素視作點,元素之間的關係視作線,存在聯絡便存在關係 需要注意的是,這裡的關係應當是1.自反的,2.對稱的,3.傳遞的 所謂合併,便是將兩個點之間 畫 一條線。又上邊的定義不難理解相連的若干點之間互相存在關係,這樣我...
演算法與資料結構(六)並查集
圖相關演算法的實現。一種不一樣的樹形結構 連線問題 connectivity problem 視覺化的來看連線問題 連線問題 左上右下是否是連線的呢?意義 實際應用中的作用 社交網路 facebook中使用者a和b中的聯絡 好友關係 是否能聯絡到。電影書籍,多 之間形成網路。網際網路網頁之間形成的網...