基于C语言的最小生成树--普里姆算法
普里姆算法(prim)
普里姆算法建立在邻接矩阵的基础之上,我们用65535来表示INFINITY,表示两个顶点之间没有关联。0表示自身,其他的数表示权值。

代码实现及讲解:
#define max 100
#define INFINITY 65535
typedef struct
{
char vex[max];
int arc[max][max];
int vexnum , edgenum ;
}MGraph;
void MGraph_init(MGraph *G) // 初始化图
{
printf("请输入顶点数和边数");
scanf_s("%d %d", &G->vexnum, &G->edgenum);
for (int i = 0; i < G->vexnum; i++) // 初始化顶点信息
{
printf("请输入顶点信息");
scanf_s(" %c", &G->vex[i]);
}
for (int i = 0; i < G->vexnum; i++) //初始化指向 0表示不指向,1表示指向
{
for (int j = 0; j < G->vexnum; j++)
{
G->arc[i][j] = INFINITY; // 默认为不指向
G->arc[i][0] = 0;
}
}
int i, j, w;
for (int k = 0; k < G->edgenum; k++) // 初始化各各顶点的指向
{
printf("输入(vi,vj)的下标i,j和指向w \n");
scanf_s("%d %d %d", &i, &j, &w);
G->arc[i][j] = w;
G->arc[j][i] = G->arc[i][j]; // 因为在矩阵中,他们是对称的
}
for (int y = 0; y < G->vexnum; y++) //打印二维数组
{
for (int u = 0; u < G->vexnum; u++)
{
printf("%d,", G->arc[y][u]);
}
printf("\n");
}
}
// 普里姆算法实现
void Prim(MGraph G)
{
int i, j, k, min;
int lowcost[max], adjvex[max]; // lowcost用于储存权值,adjvex用于储存顶点的下标
lowcost[0] = 0; // 表示将第一个V0顶点放入最小生成树中
adjvex[0] = 0;
for (i = 1; i < G.vexnum; i++)
{
lowcost[i] = G.arc[0][i]; // 将权值赋给lowcost
adjvex[i] = 0;
}
for (i = 1; i < G.vexnum; i++)
{
min = INFINITY;
j = 1;
k = 0;
while (j < G.vexnum)
{
if (lowcost[j] != 0 && lowcost[j] < min) // 不断的循环,找出权值的最小值,并且赋值给min,k做为最小值的下标
{
min = lowcost[j];
k = j;
}
j++;
}
printf("top = (%d,%d),wight = %d\n", adjvex[k], k, min); // 打印最小生成树的顶点
lowcost[k] = 0;
for (j = 1; j < G.vexnum; j++)
{
if (lowcost[j] != 0 && G.arc[k][j] < lowcost[j])
{
lowcost[j] = G.arc[k][j];
adjvex[j] = k; // 将最小值顶点的下标存入adjvex
}
}
}
}
int main()
{
MGraph G;
MGraph_init(&G);
Prim(G);
}
//测试样例
//typedef struct
//{
// char vex[max] = { 'A','B','C','D','E','F','G','H','I' };
// int arc[9][9] = { 0, 10,65535,65535,65535,11,65535,65535,65535,
// 10,65535,18,65535,65535,65535,16,65535,12,
// 0,18,65535,22,65535,65535,65535,65535,8,
// 0,65535,22,65535,20,65535,24,16,21,
// 0,65535,65535,20,65535,26,65535,7,65535,
// 11,65535,65535,65535,26,65535,17,65535,65535,
// 0,16,65535,24,65535,17,65535,19,65535,
// 0,65535,65535,16,7,65535,19,65535,65535,
// 0,12,8,21,65535,65535,65535,65535,65535 }; // 测试样例
// int vexnum = 9, edgenum = 15;
//}MGraph;
**初始化代码后,lowcost用于储存最小生成树的边权值,adjvex储存最小生成树的顶点下标 **
刚开始默认将V0做为最小生成树的根结点,并且将V0边上的权值加载到lowcost上,lowcoast的下标表示的与V0相连接的顶点,k用于储存最小值顶点下标,adjvex储存的是两个顶点之间的关系,如adjvex[8] = 1 表示是从顶点1 指向顶点8。
第一次运行,lowcost初始化后 lowcost={0,10,65535,65535,65535,11,65535,65535,65535},循环遍历
lowcost中的最小值,min =10,k=1 因为adjvex[1] = 0,表示从(0,1),之后打印(0,1)和权值
之后让lowcost[k] = 0,表示这个顶点已经访问过,防止二次访问,之后如果图中G.arc[k][j]<lowcost[j],表示的是将最小值顶点的边权值导入到lowcost中,如果G.arc[k][j],中的下标比lowcost的小,就替换lowcost[j]的值
第二次中的lowcost= {0,0,18,65535,65535,11,16,65535,12},adjvex = {0,0,1,0,0,0,1,0,1}.
后面到的运行同理:




浙公网安备 33010602011771号