1. 程式人生 > >Prim演算法與Kruskal(沒有程式碼)

Prim演算法與Kruskal(沒有程式碼)

兩個最小生成樹演算法, 都有一個共同的思想: 這棵樹是一點一點長大的; 並且每次生長, 都是貪心的.

不同之處是: Kruscal演算法是以邊為中心的, 每次找最小的並且有用的邊新增到樹上;

Prim演算法是以點為中心的, 每次找離樹最近的點新增到樹上.

我們可以把一棵樹理解成一個有智慧的生命, 可以感知它附近的點到它的距離. 每次生長枝條, 它都選擇離它最近的那個點.

點到樹的距離, 是指樹外一個點到樹上的任意點的最小距離.

所以,在程式碼實現的時候, 需要維護這樣一個數組: 樹外的點到樹的距離. 所以, 還需要區分一下點究竟在樹上還在樹外.

維護陣列就是要做兩件事: 更改陣列和呼叫陣列.

何時更改: 樹外的點到樹的距離發生變化. 這種事只能在樹生長了新的枝條的時候發生, 因為新加入的那個點可能更新了樹到樹外的某個點的距離. 同時, 新加入的那個點變成了樹上的點.

何時呼叫: 想擴張的時候, 找最近的樹外點.

一開始, 我們認為1號結點在樹上, 把它到樹的距離設為0; 其它結點的距離是INF.

在呼叫完整個演算法之後, 因為當一個節點變成樹上節點後, 我們就不再更新它到樹的距離, 所以, 原來的陣列記錄的就是它加入到樹上時的連邊長度. 對之求和, 就是樹上所有邊權之和.

Prim演算法的優勢: 稠密圖, 尤其是完全圖. 因為在Kurscal演算法中, 必須事先求出所有邊的長度才能對之排序. 但是一個有5000節點的完全圖, 這樣做的空間開銷是巨大的. Prim演算法只在更新點到樹的距離時需要用到邊長, 因此對於給座標的完全圖, 可以現用現算.