q:最小生成樹有什麼用?
a:譬如我要去五個城市旅遊,每兩個城市之間可能有路也可能沒有,路的距離可能一樣也可能不一樣,隨機從乙個城市出發,我想要把每個城市走一遍,怎麼樣走過的路距離最短,比如我想從上海出發,要走遍其他城市,要怎樣確定一條路徑最短,這就是最小生成樹的作用。
求解最小生成樹有兩種基礎演算法:普利姆演算法和克魯斯卡爾演算法。
q: 如何保證最小生成樹唯一?
a: 所有邊的權值均不相等則構成的最小生成樹一定唯一,或者有權值相等的邊,但權值相同的邊都加入到最小生成樹中,這樣的最小生成樹也唯一。
1.普利姆演算法
1.1演算法思想:
從圖中任意取出乙個頂點為起點,它可以視為一顆樹,然後在與該樹相鄰的邊中選取一條權值最小的邊,將該邊與其對應的頂點也加入到樹種,以此類推,最終將所有頂點都加入到樹中,這顆樹就是最小生成樹。一般而言,n個頂點需要執行n-1次構造過程,也就是找n-1條邊。
1.2例項分析過程
1.3**實現:
#include #define maxvertexnum 100
/* 最大頂點數設為100 */
#define maxcost 9999
/* 邊的權值最大為9999 */
typedef char vertextype;
/* 頂點型別設為字元型 */
typedef int edgetype;
/* 邊的權值設為整型 */
typedef struct
mgraph;
void createmgraph(mgraph *g)
}void prim(int gm[maxvertexnum],int tree,int cost,int n)
mgraph;
typedef struct
edgetype;
void createmgraph(mgraph *g)
}void sort(mgraph *g, edgetype e,int *edgenum) /* 用kruskal方法求最小生成樹 */
/*將邊存入陣列e中*/
for(i=0;i=0)
t=father[t];
return(t);
}void kruskal(edgetype edges,edgetype t,int m,int n)
/* 假定edges中的資料已按cost值由小到大排序 */
{ int father[maxvertexnum];
int i,j,vf1,vf2;
for(i=0;i2.4 克魯斯卡爾時間複雜度分析
克魯斯卡爾演算法的時間複雜度主要由排序演算法來決定,排序演算法處理資料的規模由圖的邊數e決定,與頂點樹無關,因此克魯斯卡爾適合用於稀疏圖。
ps:普利姆演算法與克魯斯卡爾演算法均是針對無向圖的。
最小生成樹(普利姆演算法 克魯斯卡爾演算法)
給定乙個帶權的無向連通圖,如何選取一棵生成樹,使樹上所有邊上權的總和為最小,這叫最小生成樹.求最小生成樹的演算法 1 克魯斯卡爾演算法 圖的存貯結構採用邊集陣列,且權值相等的邊在陣列中排列次序可以是任意的.該方法對於邊相對比較多的不是很實用,浪費時間.2 普里姆演算法 圖的存貯結構採用鄰接矩陣.此方...
最小生成樹(普利姆演算法 克魯斯卡爾演算法)
演算法 給定乙個帶權的無向連通圖,如何選取一棵生成樹,使樹上所有邊上權的總和為最小,這叫最小生成樹.求最小生成樹的演算法 1 克魯斯卡爾演算法 圖的存貯結構採用邊集陣列,且權值相等的邊在陣列中排列次序可以是任意的.該方法對於邊相對比較多的不是很實用,浪費時間.2 普里姆演算法 圖的存貯結構採用鄰接矩...
最小生成樹(普利姆演算法 克魯斯卡爾演算法)
給定乙個帶權的無向連通圖,如何選取一棵生成樹,使樹上所有邊上權的總和為最小,這叫最小生成樹.求最小生成樹的演算法 1 克魯斯卡爾演算法 圖的存貯結構採用邊集陣列,且權值相等的邊在陣列中排列次序可以是任意的.該方法對於邊相對比較多的不是很實用,浪費時間.2 普里姆演算法 圖的存貯結構採用鄰接矩陣.此方...