算法笔记:最小生成树
我们把构造连通网的最小代价生成树称为**最小生成树(Minimum Cost Spanning Tree)**。
找连通网的最小生成树,有两种经典的算法,普里姆算法和克鲁斯卡尔算法。
普利姆(Prim)算法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
331 // Prim算法生成最小生成树
2 void MiniSpanTree_Prim(MGraph G) {
3 int min, i, j, k;
4 int adjvex[MAXVEX]; // 保存相关顶点下标
5 int lowcost[MAXVEX]; // 保存相关顶点间边的权值
6 lowcost[0] = 0; // 初始化第一个权值为0,即v₀加入生成树
7 // lowcost的值为0,在这里就是此下标的顶点已经加入生成树
8 adjvex[0] = 0; // 初始化第一个顶点下标为0
9 for (i = 1; i < G.numVerexes; i++) { // 循环除下标为0外的全部顶点
10 lowcost[i] = G.arc[0][i]; // 将v₀顶点与之有边的权值存入数组
11 adjvex[i] = 0; // 初始化都为v₀的下标
12 }
13 for (i = 1; i < G.numVertexes; i++) {
14 min = INFINITY; // 初始化最小权值为∞,通常设置为不可能的大数字如32767、65535等
15 j = 1;
16 k = 0;
17 while (j < G.numVertexes) { // 循环全部顶点
18 if (lowcost[j]!=0 && lowcost[j]<min) { // 如果权值不为0且权值小于min
19 min = lowcost[j]; // 则让当前权值成为最小值
20 k = j; // 将当前最小值的下标存入k
21 }
22 j++;
23 }
24 printf("(%d,%d)", adjvex[k], k); // 打印当前顶点边种权值最小边
25 lowcost[k] = 0; // 将当前顶点的权值设置为0,表示此顶点已经完成任务
26 for (j = 1; j < G.numVertexes; j++) { // 循环所有顶点
27 if (lowcost[j]!=0 && G.arc[k][j] < lowcost[j]) { // 若下标为k顶点各边权值小于此前这些顶点未被加入生成树权值
28 lowcost[j] = G.arc[k][j]; // 将较小权值存入lowcost
29 adjvex[j] = k; // 将下标为k的顶点存入adjvex
30 }
31 }
32 }
33 }克鲁斯卡尔(Kruskal)算法
(我还没学)
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 怀民亦未寝。!