C语言----普利姆算法(最小生成树)

#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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值