用PRIM算法求图的最小生成树

要求
1、根据输入构造一个无向网络;
2、输出该无向网络对应的矩阵;
3、求出该无向网络的最小生成树并输出该最小生成树的所有的边。
代码

#include <stdio.h>
#include <stdlib.h>
#define  INFINITY			100000		//最大值∞
#define  MAX_VERTEX_NUM		20          //最大顶点个数
typedef  struct
{
	char    vexs[MAX_VERTEX_NUM];  		//顶点向量
	int		arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM];	//邻接矩阵
	int     vexnum, arcnum;					//图的当前顶点和弧数	
}MGraph;
typedef  struct
{
	int	adjvex;
	int	endvex;
	int   lowcost;
} closedge[MAX_VERTEX_NUM];
void CreateUDN(MGraph& G);			//创建无向网络
int LocateVex(MGraph G, char v);	//结点的在顶点向量中的下标
void PrintUDN(MGraph G);			//输出存储结构示意图
void MiniSpanTree_PRIM(MGraph G, closedge& minedge);//求最小生成树的算法
void PrintMinEdge(MGraph G, closedge minedge); //输出最小生成树的边
int main()
{
	MGraph G;//定义一个图的变量
	closedge minedge;
	CreateUDN(G);
	printf("该图的邻接矩阵存储示意图如下:\n");
	PrintUDN(G);
	printf("\n");
	MiniSpanTree_PRIM(G, minedge);
	printf("该图生成树的边如下:\n");
	PrintMinEdge(G, minedge);
	printf("\n");
	return 0;
}
void CreateUDN(MGraph& G)//采用邻接矩阵表示法,创建无向网G 
{
	int i, j, k;
	printf("请输入总顶点数,总边数,以空格隔开:\n");
	scanf_s("%d  %d", &G.vexnum, &G.arcnum);//输入总顶点数,总边数
	getchar();
	printf("依次输入点的名称,如A\n");
	for (i = 0; i <G.vexnum; i++) 
	{
		scanf_s("%c", &G.vexs[i]);       //依次输入点的信息 
	}
	for (i = 0; i < G.vexnum; i++)       //初始化邻接矩阵,边的权值均置为极大值INFINITY 
		for (j = 0; j < G.vexnum; j++)
			G.arcs[i][j] = INFINITY;
	printf("请依次输入边依附的顶点及权值,如AB 5\n");
	for (k = 0; k < G.arcnum; k++) //构造邻接矩阵 
	{							
		char v1, v2;
		char ch;
		int w;	
		getchar();//吃掉前面scanf的\n
		v1=getchar();
		v2=getchar();
		getchar();
		getchar();//边与权值间有两个空格
		scanf_s("%d",&w);//输入一条边依附的顶点及权值
		i = LocateVex(G,v1);  j = LocateVex(G,v2);		//确定v1和v2在G中的位置,即顶点数组的下标 
		G.arcs[i][j] = G.arcs[j][i] = w;				//边<v1, v2>的权值以及对称边<v2, v1>的权值为w 
	}
} //End_CreateUDN
int LocateVex(MGraph G,char v)
{
	for (int i = 0; i < G.vexnum; ++i)
	{
		if (v == G.vexs[i])
			return i;
	}
}
void PrintUDN(MGraph G)//输出邻接矩阵
{
	int i, j;
	printf("  ");
	for (i = 0; i < G.vexnum; i++)
	{
		printf("%c ", G.vexs[i]);//输出第一行的边元素
	}
	printf("\n");
	for (i = 0; i < G.vexnum; ++i)
	{
		printf("%c ", G.vexs[i]);//输出第一列的边元素
		for (j = 0; j < G.vexnum; ++j)
		{
			if (i == j)
			{
				printf("0 ");
			}
			else if(G.arcs[i][j] == INFINITY)
			{
				printf("∞ ");
			}
			else
			{
                printf("%d ", G.arcs[i][j]);
			}
		}
		printf("\n");
	}
}
void MiniSpanTree_PRIM(MGraph G, closedge& minedge)//用PRIM算法求出最小生成树
{
	int i, j, k, z;
	int temp;
	int currentmin;
	k = 0;
	for (j = 1; j < G.vexnum; ++j)// 辅助数组初始化 
	{
		minedge[j - 1].adjvex = k;
		minedge[j - 1].endvex = j;
		minedge[j - 1].lowcost = G.arcs[k][j];
	}
	for (i = 0; i < G.vexnum - 1; ++i)
	{
		currentmin = minedge[i].lowcost;
		k = i;
		for (j = i + 1; j < G.vexnum - 1; j++)//选择最小的边
		{
			if (minedge[j].lowcost < currentmin)
			{
				currentmin = minedge[j].lowcost;
				k = j;
			}
		}
		{//第k个元素与第i个进行交换
			temp = minedge[i].adjvex;
			minedge[i].adjvex = minedge[k].adjvex;
			minedge[k].adjvex = temp;
			temp = minedge[i].endvex;
			minedge[i].endvex = minedge[k].endvex;
			minedge[k].endvex = temp;
			temp = minedge[i].lowcost;
			minedge[i].lowcost = minedge[k].lowcost;
			minedge[k].lowcost = temp;
		}
		for (j = i + 1; j < G.vexnum - 1; ++j)
		{
			z = minedge[i].endvex;//z为找到的新顶点
			k = minedge[j].endvex;
			if (k != z)
			{
				if (G.arcs[z][k] < minedge[j].lowcost)
				{
					minedge[j].adjvex = z;
					minedge[j].lowcost = G.arcs[z][k];
				}
			}
		}
	}
} // MiniSpanTree
void PrintMinEdge(MGraph G, closedge minedge)//输出该最小生成树的所有的边
{	
	int i;
	for (i = 0; i < G.vexnum-1; i++)
	{
		printf("%c%c %d\n", G.vexs[minedge[i].adjvex], G.vexs[minedge[i].endvex],minedge[i].lowcost);
	}
}
**输入样例**
5  8
ABCDE
AB  8
AC  4
AE  3
BD  8
BE  6
CD  10
CE  13
DE  12
**输出样例**
![在这里插入图片描述](https://img-blog.csdnimg.cn/20201208230215245.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzUxMjI0NDky,size_16,color_FFFFFF,t_70)

猜你喜欢

转载自blog.csdn.net/qq_51224492/article/details/110912745