最小生成樹(Minimum Spanning Tree, MST)是圖論核心問題,廣泛應用於網絡設計、電路佈線、聚類分析等領域。Prim 算法作為構造 MST 的經典貪心算法,以 O(n²) 時間複雜度成為稠密圖的首選。本文從原理、步驟、代碼實現到運行演示全方位講解。
給定連通網 G=(V,E),權值為邊的代價。Prim 算法思想:
關鍵數據結構:edge[] 數組動態維護從 U 到 V-U 的最小代價邊,每次選擇後更新。
edge[],記錄起始頂點到其餘頂點的最小邊。cost=0)。edge[] 中找 cost>0 且最小的邊;edge[] 中未入樹頂點的最小邊。typedef struct { int start, end, cost; } Edge;
void Prim_MG(MGraph MG, char vs) {
Edge edge[MAX_VEX_NUM];
int i, j, k, v, min;
int s = getIndexOfVexs(vs, &MG);
// 1. 初始化邊數組
for (i = 1; i <= MG.vexnum; i++) {
if (s != i) {
edge[i].start = s;
edge[i].end = i;
edge[i].cost = MG.arcs[s][i];
}
}
edge[s].cost = 0; // 起點入樹
// 2. 選擇 n-1 條邊
for (i = 2; i <= MG.vexnum; i++) {
min = UN_REACH;
for (j = 1; j <= MG.vexnum; j++)
if (edge[j].cost != 0 && edge[j].cost < min) {
min = edge[j].cost; k = j;
}
v = edge[k].end;
edge[v].cost = 0; // 新頂點入樹
printf("%c %c %d\n", MG.vexs[edge[v].start], MG.vexs[edge[v].end], MG.arcs[edge[v].start][edge[v].end]);
// 3. 更新邊數組
for (j = 1; j <= MG.vexnum; j++)
if (edge[j].cost != 0 && MG.arcs[v][j] != 0 && MG.arcs[v][j] < edge[j].cost) {
edge[j].start = k;
edge[j].end = j;
edge[j].cost = MG.arcs[v][j];
}
}
}
包含圖的創建(鄰接矩陣)、打印、Prim 算法調用及主函數,支持有向/無向圖輸入。
/* 完整代碼見原文,關鍵結構定義: */
#define MAX_VEX_NUM 50
#define UN_REACH 1000
typedef char VertexType;
typedef enum { DG, UDG } GraphType;
typedef struct {
VertexType vexs[MAX_VEX_NUM];
int arcs[MAX_VEX_NUM][MAX_VEX_NUM];
int vexnum, arcnum;
GraphType type;
} MGraph;
/* ... create_MG, print_MG, getIndexOfVexs, main 等輔助函數 ... */
輸入: 無向圖,4頂點(a,b,c,d),5條邊 a-b:1 a-c:3 a-d:4 b-c:2 c-d:3 起始頂點:a 輸出: a b 1 b c 2 c d 3 // 總權值 6,構成最小生成樹