#include<stdio.h>
#include<stdlib.h>
#define MAXVEX 20/*最大顶点个数*/
#define INFINITY 32767/*表示无穷,可自定义*/
#define ELem int
#define FALSE 0
#define OK 1
#define TRUE 1
typedef char VertexType;
typedef struct {
int arcs[MAXVEX][MAXVEX]; //邻接矩阵,边的信息
VertexType vexs[MAXVEX]; //顶点信息
int vexnum; //顶点数目
int arcnum; //边(弧)数目
}AdjMatrix;
typedef struct { //数组元素的下标对应图G的顶点序号
int adjvex; /*记录该顶点和顶点集合中相连权值最小的顶点序号*/
int lowcost; /*记录最小的权值*/
}Closedge;
//根据名称得到指定顶点在顶点集合中的下标
int getIndexOfVexs(char vex, AdjMatrix* MG)
{
for (int i = 1; i <= MG->vexnum; i++)
{
if (MG->vexs[i] == vex) return i;
}
return 0;
}
void Create(AdjMatrix* MG) {
int v1, v2;
char c1, c2;
printf("请输入顶点数目:");
scanf("%d", &MG->vexnum);
printf("请输入边的数目:");
scanf("%d", &MG->arcnum);
getchar();
//输入各顶点信息
for (int i = 1; i <= MG->vexnum; i++)
{
printf("请输入第%d个顶点(char): ", i); //请输入各顶点信息
scanf("%c", &MG->vexs[i]);
getchar();
}
//初始化邻接矩阵
for (int i = 1; i <= MG->vexnum; i++)
for (int j = 1; j <= MG->vexnum; j++)
MG->arcs[i][j] = INFINITY; /*如果是网则赋值INFINITY */
//输入边的信息,建立邻接矩阵
for (int k = 1; k <= MG->arcnum; k++)
{
printf("请输入第%d个边连接的两个顶点及权值v1(char) v2(char) weight(int): ", k); //请输入有关系的两个顶点
int weight = INFINITY;
scanf("%c %c %d", &c1, &c2, &weight);
v1 = getIndexOfVexs(c1, MG);
v2 = getIndexOfVexs(c2, MG);
MG->arcs[v1][v2] = weight;
MG->arcs[v2][v1] = weight; //无向图为对称矩阵
getchar();
}
}
//打印图的信息
void Printf(AdjMatrix MG)
{
printf("顶点数目为: %d\n", MG.vexnum);
printf("边的数目为: %d\n", MG.arcnum);
printf("顶点: ");
for (int i = 1; i <= MG.vexnum; i++)
printf("%c", MG.vexs[i]);
printf("\n邻接矩阵为: \n");
for (int i = 1; i <= MG.vexnum; i++)
{
for (int j = 1; j <= MG.vexnum; j++) {
if (MG.arcs[i][j] == INFINITY) printf("#");
else printf("%d", MG.arcs[i][j]);
}
printf("\n");
}
}
/****************最小生成树(Prim算法)***************/
void Prim(AdjMatrix G, int start) {
Closedge closedge[MAXVEX];
closedge[start].lowcost = 0; /*标志顶点加入到生成树集合中*/
//初始化剩下的所有顶点对应的closedge数组
for (int i = 1; i <= G.vexnum; i++) {
if (i != start) {
closedge[i].adjvex = start;
closedge[i].lowcost = G.arcs[start][i];
}
}
printf("\n最小生成树的生成过程:");
//从边集中选出n-1条符合条件的边
for (int e = 1; e <= G.vexnum - 1; e++) {
int m;//记录顶点
int min = INFINITY;//记录最小权值
//找出当前closedge没有进入生成树的顶点中的lowcost最小值对应的顶点
for (int k = 1; k <= G.vexnum; k++) {
if ((closedge[k].lowcost != 0) && closedge[k].lowcost < min) {
min = closedge[k].lowcost;
m = k;
}
}
printf("\n(%c,%c) %d", G.vexs[closedge[m].adjvex], G.vexs[m], min);
closedge[m].lowcost = 0;/*标志顶点m进入生成树集合*/
//用新的生成树顶点m 更新closedge数组
for (int i = 1; i <= G.vexnum; i++) {
if ((closedge[i].lowcost != 0) && G.arcs[m][i] < closedge[i].lowcost) {
//如果发现有更小的权值边出现,则替换原有信息
closedge[i].lowcost = G.arcs[m][i];
closedge[i].adjvex = m;
}
}
}
}
int main() {
AdjMatrix MG, T;
Create(&MG);
Prim(MG, 1);
return 0;
}
C语言----普利姆算法(最小生成树)
最新推荐文章于 2023-06-17 13:25:05 发布