普利姆演算法和克魯斯卡爾演算法求解最小生成樹

2021-09-27 13:01:24 字數 1567 閱讀 6027

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 普里姆演算法 圖的存貯結構採用鄰接矩陣.此方...