Geeks Union-Find Algorithm Union By Rank and Path Compression 圖環演算法

來源:互聯網
上載者:User

同樣是尋找一個圖是否有環的演算法,但是這個演算法很牛逼,構造樹的時候可以達到O(lgn)時間效率。n代表頂點數

原因是根據需要縮減了樹的高度,也叫壓縮路徑(Path compression),名字很高深,不過其實不難理解,簡單來說就是每次尋找一個節點的時候,都把這一路徑中的所有節點都賦予根節點作為路徑。


原文沒指出的地方:

也因為需要壓縮,所以初始化的時候注意,不能如前面簡單實用Union Find的演算法那樣初始化所有頂點的父母節點為-1,應該是初始化所有節點的父母節點為本身(自己繁殖自己?),然後就方便遞迴的時候一律可以返回這個跟節點了。 

當然其實初始化為-1也是可以的,不過需要額外代碼處理一下,也不難。


最後可以參考原文:http://www.geeksforgeeks.org/union-find-algorithm-set-2-union-by-rank/


#pragma once#include <iostream>class UnionFindUnionByRank{struct Edge{int src, des;};struct Graph{int V, E;Edge *edges;Graph(int v, int e) : V(v), E(e){edges = new Edge[e];}~Graph(){if (edges) delete [] edges;}};struct subSet{int parent, rank;};int find(subSet *subs, int i){//因為要壓縮,所以不能使用-1作為根的標誌了if (subs[i].parent != i){//Union by rank: attach smaller rank tree to high rank tree. It is so simple, but very hard to create it totally by ourself, so it's good to stand on the shoulder of the giant.subs[i].parent = find(subs, subs[i].parent);}return subs[i].parent;//因為如果-1作為根標誌,那麼這裡就要返回i,就達不到壓縮的效果了,而是應該返回parent,一層一層遞迴回上一層。}void unionTwo(subSet *subs, int x, int y){int xroot = find(subs, x);int yroot = find(subs, y);if (subs[xroot].rank < subs[yroot].rank){subs[xroot].parent = yroot;}else if (subs[xroot].rank > subs[yroot].rank){subs[yroot].parent = xroot;}else{//only need to increment its rank when ther are equal ranksubs[yroot].parent = xroot;subs[xroot].rank++;}}bool isCycle(Graph *gra){subSet *subs = new subSet[gra->V];for (int i = 0; i < gra->V; i++){subs[i].parent = i;//parent不能初始化為-1subs[i].rank = 0;}for (int e = 0; e < gra->E; e++){int x = find(subs, gra->edges[e].src);int y = find(subs, gra->edges[e].des);if (x == y) return true;unionTwo(subs, x, y);}return false;}public:UnionFindUnionByRank(){int V = 3, E = 3;struct Graph* graph = new Graph(V, E);// add edge 0-1graph->edges[0].src = 0;graph->edges[0].des = 1;// add edge 1-2graph->edges[1].src = 1;graph->edges[1].des = 2;// add edge 0-2graph->edges[2].src = 0;graph->edges[2].des = 2;if (isCycle(graph))printf( "Union By Rank found graph contains cycle \n" );elseprintf( "Union By Rank found graph doesn't contain cycle \n" );}};



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.