貪心算法(Greedy Algorithm)之最小生成樹 克魯斯卡爾算法(Kruskal's algorithm)

克魯斯卡爾算法(Kruskal's algorithm)是兩個經典的最小生成樹算法的較爲簡單理解的一個。這裏面充分體現了貪心算法的精髓。大致的流程可以用一個圖來表示。這裏的圖的選擇借用了Wikipedia上的那個。非常清晰且直觀。

 

首先第一步,我們有一張圖,有若干點和邊

如下圖所示:

graph

第一步我們要做的事情就是將所有的邊的長度排序,用排序的結果作爲我們選擇邊的依據。這裏再次體現了貪心算法的思想。資源排序,對局部最優的資源進行選擇。

排序完成後,我們率先選擇了邊AD。 這樣我們的圖就變成了

圖1

第二步,在剩下的變中尋找。我們找到了CE。這裏邊的權重也是5

圖二

依次類推我們找到了6,7,7。完成之後,圖變成了這個樣子。

圖三

下一步就是關鍵了。下面選擇那條邊呢? BC或者EF嗎?都不是,儘管現在長度爲8的邊是最小的未選擇的邊。但是現在他們已經連通了(對於BC可以通過CE,EB來連接,類似的EF可以通過EB, BA, AD, DF來接連)。所以我們不需要選擇他們。類似的BD也已經連通了(這裏的連通線用紅色表示了)。所以最後就剩下EG和FG了。當然我們選擇了EG。 最後成功的圖就是下圖:

圖四

到這裏所有的邊點都已經連通了,一個最小生成樹構建完成。

如果要簡要得描述這個算法的話就是,首先邊的權重排序。(從小到大)循環的判斷是否需要選擇這裏的邊。判斷的依據則是邊的兩個頂點是否已經連通,如果連通則繼續下一條。不連通就選擇使其連通。這個流程還是非常清晰明瞭。

 

但是在實現的時候,困難的地方在於如何描述2個點已然連通? 這裏用到了並查集做輔助,至於並查集可以到這裏去看看。

這裏貼出並查集的代碼和Kruscal的C++實現:

 

 

發佈了70 篇原創文章 · 獲贊 9 · 訪問量 47萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章