数据结构_图_prim最小生成树算法

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<limits.h>
#define MAX_VERTEX_NUM 20
typedef enum{DG, DN, UDG, UDN} GraphKind;
typedef int VRType;			//边的信息
typedef char VertexType;		//顶点的信息
typedef struct ArcCell{
	VRType adj;						//保存边的权值
}ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];//图的邻接矩阵,保存边的信息
typedef struct{
	VertexType vex[MAX_VERTEX_NUM];		//保存顶点的信息,在本图中,顶点的信息由字符表示
	AdjMatrix arcs;						//图的邻接矩阵
	int vexnum, arcnum;					//保存图的顶点数和边数
	GraphKind kind;						//图的种类
}MGraph;
typedef struct{			//辅助数组,记录U到V-U的代价最小的边的辅助数组
	VertexType adjvex;	//顶点集U到该点为最小权值的那个顶点的序号
	VRType lowcost;		//上面adjvex顶点到这个顶点的最小权值
}minside[MAX_VERTEX_NUM];
int LocateVex(MGraph G, VertexType u){			//寻找顶点在图中的序号
	int i = 0;
	for(i = 0; i < G.vexnum; i++)
		if(G.vex[i] == u)
			return i;
	return -1;
}
int minimum(minside SZ, MGraph G){//在辅助数组中找到权值最小的边
	int i, j, min, k;
	for(i = 0; SZ[i].lowcost==0; i++)//找到第一个不为0的SZ[i].lowcost的位置
		;
	min = SZ[i].lowcost;
	k = i;
	for(j = 0; j < G.vexnum; j++)
		if(SZ[j].lowcost > 0 && SZ[j].lowcost < min){
			min = SZ[j].lowcost;
			k = j;
		}
	return k;
}
void MiniSpanTree_Prim(MGraph G, VertexType u){
	minside closedge;//定义辅助数组
	int i, j;
	int k = LocateVex(G, u);
	for(j = 0; j < G.vexnum; j++)//辅助数组初始化,此时讲u这个点包含到U中。
		if(j != k){
			closedge[j].adjvex = u;					//此时数组中距离都是顶点u到其它所有结点的距离
			closedge[j].lowcost = G.arcs[k][j].adj;//顶点u到所有结点的权值
		}
	closedge[k].lowcost = 0;			//值为0表示该点以进入到集合U中
	printf("最小代价生成树的各条边为\n");
	for(i = 1; i < G.vexnum; i++){
		k = minimum(closedge,G);
		printf("加入的第%d条为%c到%c\n", i, closedge[k].adjvex, G.vex[k]);
		closedge[k].lowcost = 0;		//值为k的结点进如U中
		for(j = 0; j < G.vexnum; j++)	//与k相关联的结点,如果U中k节点到V-U的结点距离小于以前的距离,则修改辅助数组的值
			if(G.arcs[k][j].adj < closedge[j].lowcost)
			{
				closedge[j].adjvex = G.vex[k];
				closedge[j].lowcost = G.arcs[k][j].adj;
			}
	}
}
int main()
{
	FILE * p_file;
	if(!(p_file = fopen("D:\\test.txt","r")))
	{
		printf("open error\n");
		return 0;
	}
	int i, j;
	MGraph G;
	G.kind = DG;
	G.arcnum = 10;
	G.vexnum = 6;
	for(i = 0; i< G.vexnum;i++)
		G.vex[i] = (char)(97 + i);
	char tail[MAX_VERTEX_NUM], head[MAX_VERTEX_NUM];//保存所有边的起始位置和终点位置
	int cost[MAX_VERTEX_NUM];//保存相对应边的权值
	for(i = 0; i < G.arcnum;i++)
	{
		fscanf(p_file, "%c%c%d",&tail[i], &head[i], &cost[i]);
	}
	for(i = 0; i < G.vexnum;i++)
		for(j = 0; j < G.vexnum; j++)
			G.arcs[i][j].adj = SHRT_MAX;
	for(i = 0; i < G.arcnum;i++){
		int m = LocateVex(G, tail[i]);
		int n = LocateVex(G, head[i]);
		G.arcs[m][n].adj = cost[i]; 
		G.arcs[n][m].adj = cost[i];
	}
	for(i = 0; i < G.vexnum;i++){
		for(j = 0; j < G.vexnum; j++)
			printf("%6d ",G.arcs[i][j].adj);
		printf("\n");
	}
	MiniSpanTree_Prim(G, 'a');
}

txtz中保存的数据如下,ab6be3ef6fd2da5ac1bc5dc5ec6fc4。

其中v1到v6在代码中用点a到点f来表示。如代码有错误,望不吝赐教!


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值