目录
一个连通图的生成树是指一个极小连通子图,它含有图中的全部顶点,但只有足以构成一棵树的 n-1 条边。在一个连通网的所有生成树中,各边代价之和最小的那棵生成树称为该连通网 最小代价生成树(MST),简称为 最小生成树。
利用 普里姆(Prim)算法和 克鲁斯卡尔(Kruskal)算法可以生成一个连通网的最小代价生成树。
1. 普里姆(Prim)算法
1.1 实现步骤
基本步骤:
假设N=(V,{E})是连通网,,TE为最小代价生成树中边的集合。
① 初始U={u0}(u0∈V),TE=空集;
② 在所有u∈U,v∈V-U的边中选一条代价最小的边(u0,v0)并入集合TE,同时将v0并入U;
③ 重复②,直到U=V为止。
即每次选择某一顶点的权值最小的边。
示例:
1.2 完整实现代码+注释
# include<stdio.h>
# define MAX_VERTEX_NUM 20 //最多顶点个数
# define INFINITY 32768
/*图的邻接矩阵存储结构*/
typedef char VertexData;
typedef struct {
VertexData vertex[MAX_VERTEX_NUM]; //顶点向量
int arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; //邻接矩阵
int vexnum, arcnum; //图的顶点数和弧数
}AdjMatrix;
AdjMatrix G;
/*求顶点位置函数*/
int LocateVertex(AdjMatrix* G, VertexData v) {
int k;
for (k = 0; k < G->vexnum; k++) {
if (G->vertex[k] == v)
break;
}
return k;
}
/*创建一个无向网*/
void CreateAdjMatrix(AdjMatrix* G) {
int i, j, k, weight;
VertexData v1, v2;
printf("请输入图的顶点数和弧数:");
scanf("%d%d", &G->vexnum, &G->arcnum); //输入图的顶点数和弧数
for (i = 0; i < G->vexnum; i++) {
//初始化邻接
for (j = 0; j < G->vexnum; j++)
G->arcs[i][j] = INFINITY;
}
printf("请输入图的顶点:");
for (i = 0; i < G->vexnum; i++)
scanf(" %c", &G->vertex[i]); //输入图的顶点
for (k = 0; k < G->arcnum; k++) {
printf("请输入第%d条弧的两个顶点和权值:", k + 1)