Prim算法求MST(最小生成树)

Prim算法求最小生成树使用的图的存储结构是图的邻接矩阵

#include<stdio.h>

#define MAX_VERTAX_SIZE 20
#define INFINITE	65535
#define OK 		1
#define ERROR 		0

//图的邻接矩阵表示的结构定义
typedef int Status;
typedef char VertaxElemType;
typedef struct GraphAM{
	VertaxElemType VertaxArray[MAX_VERTAX_SIZE];
	int AdjacencyMatrix[MAX_VERTAX_SIZE][MAX_VERTAX_SIZE];
	int vertaxNum;
	int eageNum;
}GraphAM;

//用于Prim算法的辅助结构:
typedef struct MinCostEage{
	VertaxElemType vertax;
	int lowCost;
}MinCostEage;

int LocateVertax(GraphAM G, VertaxElemType c){
	int i;
	for( i = 0; i < G.vertaxNum; i++ ){
		if( c == G.VertaxArray[i] )
			return i;
	}
	return -1;
}
Status CreateUDG(GraphAM* G){
	int i,j,index_v,index_w, weight;
	VertaxElemType v,w;
	printf("  Greate UndiGraph with Cost\n");
	printf("Please enter the number of Vertax and Eage:");
	scanf("%d %d%*c", &(G->vertaxNum), &(G->eageNum));

	printf("ok, please enter the value of the vertaxes:\n");
	for( i = 0; i < G->vertaxNum; i++ ){
		scanf("%c%*c", &(G->VertaxArray[i]));
	}
	for( i = 0; i < G->vertaxNum; i++ )
		for( j = 0; j < G->vertaxNum; j++ )
			G->AdjacencyMatrix[i][j] = INFINITE;
	for( i = 0; i < G->eageNum; i++ ){
		printf("ok,please enter the two Vertax and Wight of eage %d,\nNote:Seperated by Space: ", i+1);
		scanf("%c %c %d%*c", &v, &w, &weight);
		if( LocateVertax(*G, v) != -1 )
			index_v = LocateVertax(*G, v);
		else
			return ERROR;
		if( LocateVertax(*G, w) != -1 )
			index_w = LocateVertax(*G, w);
		else
			return ERROR;
		G->AdjacencyMatrix[index_v][index_w] = G->AdjacencyMatrix[index_w][index_v] = weight;
	}
	return OK;
}
void PrintAdjacencyMatrix(GraphAM G){
	printf("Show the Adjacency Matrix of Graph('#' repersents infinite)\n");
	int i,j;
	for( i = 0; i < G.vertaxNum; i++ ){
		for( j = 0; j< G.vertaxNum; j++ ){
			if( G.AdjacencyMatrix[i][j] != INFINITE )
				printf("%5d", G.AdjacencyMatrix[i][j]);
			else
				printf("    #");
		}
		printf("\n\n");
	}
}
//求图G的最小生成树,从顶点v开始
Status Prim(GraphAM G, VertaxElemType v){
	int i,index_v,min,min_index,j;
	index_v = LocateVertax(G, v);				
	MinCostEage minCost[MAX_VERTAX_SIZE];				//数组的下标隐含是第几个顶点
	for( i = 0; i < G.vertaxNum; i++ ){		
		minCost[i].lowCost = G.AdjacencyMatrix[index_v][i]; 	//初始化数组为起始顶点的AdjacencyMatrix[起始顶点]信息
		minCost[i].vertax = v;				    	//MST中的哪个顶点与数外有本数组元素中的lowCost值
	}
	minCost[index_v].lowCost = 0;					//已经在MST中的标志,使得没有机会参加数组中lowCost的选取
	printf("MST(Minimum Cost Spinning Tree):\n");
	for( i = 1; i < G.vertaxNum; i++ ){
		for( j = 0; j < G.vertaxNum; j++ ){			//找第一个非0的作为min,为了避免第一个是0
			if( minCost[j].lowCost != 0 ){
				min = minCost[j].lowCost;
				min_index = j;
				break;
			}
		}
		for( j = 0; j < G.vertaxNum; j++ ){			//寻找该数组中的当前的最小权值
			if( minCost[j].lowCost > 0 && minCost[j].lowCost < min ){
				min = minCost[j].lowCost;
				min_index = j;
			}
		}
		printf("(%c, %c)\t", minCost[min_index].vertax, G.VertaxArray[min_index]);//数组的下标存储了第二个%c的需要的信息,
											  //vertax域提供了第一个%c需要的信息
		minCost[min_index].lowCost = 0;
		for( j = 0; j < G.vertaxNum; j++ ){
			if( G.AdjacencyMatrix[min_index][j] < minCost[j].lowCost ){
				minCost[j].lowCost = G.AdjacencyMatrix[min_index][j];
				minCost[j].vertax = G.VertaxArray[min_index];
			}
		}
	}
}
/* minCost数组:该数组是结构数组,即每个元素是一个结构类型。该结构有两个域:lowCost用来保存所有已经在
 * 		最小生成树中的顶点,到所有还没有在最小生成树中的顶点的所有权值中的最小的;vertax域用
 * 		来保存是哪个在最小生成树中的顶点拥有着这个最小的权值。并且这个数组的下标隐含着顶点的
 * 		信息。例如,第2个数组元素在程序运行中的某一个时刻表示:已经形成的MST中的vertax顶点到
 * 		图中的第2个顶点的权值为lowCost,并且是树内顶点和数外顶点链接的最小的权值。
 * 		所以这个数组要不断的更新。
 * 		假设整个生成树的过程从顶点a开始,那么这个数组的初始元素为该图的邻接矩阵中顶点a的一行
 * 		(该行表示的是a于其他的顶点的权值),并且将数组的vertax都设置为a。表示从MST中的顶点a到
 * 		数外的所有顶点的权值,然后从该数组中选出lowCost最小的值。为生成树的第二个顶点。
 * 		现在树中有两个顶点,所以需要比较是哪个顶点和数外的其他顶点的权值比较小,minCost数组
 * 		中的信息是树中顶点到其他顶点的最小权值,所以和将要加入的新的顶点的邻接矩阵中的一行(
 * 		存放的是该顶点与所有其他的顶点的权值)
 * 		进行比较即可,小的就更新。
 * */
int main(){
	GraphAM G;
	CreateUDG(&G);
	PrintAdjacencyMatrix(G);
	Prim(G, 'a');
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值