並查集(Disjoint Set)用來判斷已有的數據是否構成環。web
在構造圖的最小生成樹(Minimum Spanning Tree)時,若是採用 Kruskal 算法,每次添加最短路徑前,須要先用並查集來判斷一下這個路徑是否會構成環。算法
遍歷圖的每一條邊,按照下面的原則將對應的兩個頂點添加到集合中:數組
爲了代碼上的統一性,能夠在開始前,把全部頂點都當作只有一個元素的集合,而後就是不停的合併集合。svg
集合能夠用樹的雙親表示法來表示,只須要額外建立一個數組便可。爲了簡化合並操做,能夠每次都只操做兩顆樹的根結點。spa
int parent[n]; // 查找樹的根結點 int findRoot(int parent[], int key) { int root = key; while (parent[root] != -1) { root = parent[root]; } return root; } // 合併樹 int unionVertex(int parent[], int x, int y) { int lRoot = findRoot(parent, x); int rRoot = findRoot(parent, y); // 兩個結點的根結點爲同一個,則這兩個結點屬於同一棵樹 if (lRoot == rRoot) { return 0; } // 不然,合併樹,這裏直接把左樹做爲右樹的子樹,可能會致使不平衡 parent[lRoot] = rRoot; }
爲了在每次合併時,儘量保證樹的平衡,再建立一個數組保存樹的高度,合併時將高度低的樹做爲子樹便可。code
#include <stdio.h> void init(int parent[], int height[], int count) { int i; for (i = 0; i < count; i++) { parent[i] = -1; height[i] = 0; } } int findRoot(int parent[], int key) { int root = key; while (parent[root] != -1) { root = parent[root]; } return root; } int unionVertex(int parent[], int height[], int x, int y) { int lRoot = findRoot(parent, x); int rRoot = findRoot(parent, y); if (lRoot == rRoot) { return 0; } // parent[lRoot] = rRoot; if (height[lRoot] < height[rRoot]) { parent[lRoot] = rRoot; } else if (height[rRoot] < height[lRoot]) { parent[rRoot] = lRoot; } else { parent[lRoot] = rRoot; height[rRoot]++; } return 1; } int main(void) { int edgeCount = 6, vertexCount = 5; int i; // 圖中的邊 int graph[5][2] = { {0, 1}, {2, 4}, {1, 2}, {1, 3}, {2, 5} }; int parent[edgeCount]; int height[edgeCount]; init(parent, height, edgeCount); for (i = 0; i < vertexCount; i++) { int ret = unionVertex(parent, height, graph[i][0], graph[i][1]); if (ret == 0) { printf("%d, %d\n", graph[i][0], graph[i][1]); printf("find cycle!\n"); return 0; } } printf("no find cycle!\n"); for (i = 0; i < vertexCount; i++) { printf("%d's parent is: %d\n", i, parent[i]); } for (i = 0; i < vertexCount; i++) { printf("%d's height is: %d\n", i, height[i]); } return 0; }
執行結果:xml
no find cycle! 0's parent is: 1 1's parent is: 4 2's parent is: 4 3's parent is: 4 4's parent is: -1 0's height is: 0 1's height is: 1 2's height is: 0 3's height is: 0 4's height is: 2