添加链接描述
运行了一下prim 算法 觉得这个程序还可以 后期可以在此基础上做较大的改动 故此分享了这个代码
#include <stdio.h>
#define MAXVEX 10
#define TRUE 1
#define FALSE 0
#define INF 65535//此处是权值极大值
#define LENGTH(a) (sizeof(a) / sizeof(a[0]))
typedef char VertexType;
typedef struct
{
VertexType vexs[MAXVEX];//存储顶点信息
int arc[MAXVEX][MAXVEX];//邻接矩阵
int numVertexes, numEdges;//边数和点数
}MGraph;
//创建一个图
void CreateMGraphExample(MGraph *G)
{
VertexType vexs[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8'};//存储的顶点
int arc[][9] = {
{0, 10, INF, INF, INF, 11, INF, INF, INF},
{10, 0, 18, INF, INF, INF, 16, INF, 12},
{INF, 18, 0, 22, INF, INF, INF, INF, 8},
{INF, INF, 22, 0, 20, INF, INF, 16, 21},
{INF, INF, INF, 20, 0, 26, INF, 7, INF},
{11, INF, INF, INF, 26, 0, 17, INF, INF},
{INF, 16, INF, INF, INF, 17, 0, 19, INF},
{INF, INF, INF, 16, 7, INF, 19, 0, INF},
{INF, 12, 8, 21, INF, INF, INF, INF, 0}
};
G->numVertexes = LENGTH(vexs);//顶点数赋值
G->numEdges = 0;
for(int i = 0; i < G->numVertexes; i++)
G->vexs[i] = vexs[i];//给图的顶点数组赋值
for(int i = 0; i < G->numVertexes; i++)
{
for(int j = 0; j < G->numVertexes; j++)
{
G->arc[i][j] = arc[i][j];//给图的邻边矩阵赋值
}
}
for(int i = 0; i < G->numVertexes; i++)
{
for(int j = 0; j < G->numVertexes; j++)
{
if(i != j && G->arc[i][j] != INF)
{
G->numEdges++;//统计图中出现的边数 因为是无向图 这里是二倍的关系
}
}
}
printf("%d %d\n", G->numVertexes, G->numEdges / 2);//这里在计算图的边数的时候 除了2
}
//这里是可以手动创建图的函数
//由于上面的函数给了示例 如果想要自己手动输入函数 可以在这里修改
void CreateMGraph(MGraph *G)/* 构件图 */
{
int i, j;
/* printf("请输入边数和顶点数:"); */
G->numEdges=15;
G->numVertexes=9;
for (i = 0; i < G->numVertexes; i++)/* 初始化图 */
{
for ( j = 0; j < G->numVertexes; j++)
{
if (i==j)
G->arc[i][j]=0;
else
G->arc[i][j] = G->arc[j][i] = INF;
}
}
G->arc[0][1]=10;
G->arc[0][5]=11;
G->arc[1][2]=18;
G->arc[1][8]=12;
G->arc[1][6]=16;
G->arc[2][8]=8;
G->arc[2][3]=22;
G->arc[3][8]=21;
G->arc[3][6]=24;
G->arc[3][7]=16;
G->arc[3][4]=20;
G->arc[4][7]=7;
G->arc[4][5]=26;
G->arc[5][6]=17;
G->arc[6][7]=19;
for(i = 0; i < G->numVertexes; i++)
{
for(j = i; j < G->numVertexes; j++)//注意 这里j的起点是从i开始的
{
G->arc[j][i] =G->arc[i][j];//因为是无向图 所以顶点具有对称性
}
}
}
/* Prim 算法生成最小生成树 */
void MiniSpanTree_Prim(MGraph G)
{
int min, i, j, k; // min 为当前权值最小值
int lowcost[MAXVEX]; /* 保存顶点间边的权值 */
int adjvex[MAXVEX]; /* 保存相关顶点的下标,即下标与其值所连边为当前最小权值边 */
lowcost[0] = 0; /* 选取第一个顶点为起始点, 即 v0 加入树, lowcost的值为0,在这里就是此下标的顶点已经加入生成树 */
adjvex[0] = 0; /* 初始化第一个顶点下标为0 */
for(i = 1; i < G.numVertexes; i++) /* 循环除下标为 0 外的全部顶点 */
{
lowcost[i] = G.arc[0][i]; /* 将与 v0 顶点有边的权值存入数组 就是遍历所有与v0相邻的边*/
adjvex[i] = 0; /* 将其他所有顶点的值初始化为 v0 的下标 */
}
for(i = 1; i < G.numVertexes; i++)
{
min = INF; /* 初始化最小权值为 无穷大 */
j = 1, k = 0;//因为我们一开始是从0开始的 所以这里的j改成了从1开始
while(j < G.numVertexes) /* 循环全部顶点,寻找当前最小生成树顶点集合中最小权值的边 */
{
if(lowcost[j] != 0 && lowcost[j] < min) /* 如果权值不为 0(即不在树中),这!=0的意思就是这个顶点还没有放到树中 且权值小于 min */
{
min = lowcost[j]; /* 则让当前权值成为最小值 */
k = j; /* 将当前最小值的下标存入k */
}
j++;
}
lowcost[k] = 0; /* 将当前顶点的权值设置为0, 表示此顶点已加入树的顶点集合 取k位置的顶点 并将其加入到树中去 */
printf("(%d, %d)", adjvex[k], k); /* 打印当前顶点边中权值最小的边 */
for(j = 1; j < G.numVertexes; j++) /* 循环所有顶点 */
{
/* 如果下标为 k 的顶点边集中权值小于已存在的权值, 比如 (v0, v6)权值为INF, 而(v1, v6)权值为 16, 更新*/
if(lowcost[j] != 0 && G.arc[k][j] < lowcost[j])
{
lowcost[j] = G.arc[k][j]; /* 将较小的权值存入 lowcost 相应位置 */
adjvex[j] = k; /* 将下标为 k 的顶点存入 adjvex */
}
}
}
}
int main() {
MGraph G;
CreateMGraphExample(&G);
// CreateMGraph(&G);
MiniSpanTree_Prim(G);
printf("Hello, World!\n");
return 0;
}
这是运行的结果
9 14
(0, 1)(0, 5)(1, 8)(8, 2)(1, 6)(6, 7)(7, 4)(7, 3)Hello, World!
关于prim算法的知识请查阅书本!!!