码迷,mamicode.com
首页 > 其他好文 > 详细

_DataStructure_C_Impl:图的最小生成树

时间:2015-08-11 07:23:34      阅读:179      评论:0      收藏:0      [点我收藏+]

标签:数据结构

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef char VertexType[4];
typedef char InfoPtr;
typedef int VRType;
#define INFINITY 10000		//定义一个无限大的值
#define MaxSize 50	 //最大顶点个数
typedef enum{DG,DN,UG,UN}GraphKind;		//图的类型:有向图、有向网、无向图和无向网

typedef struct{
	VRType adj;		//对于无权图,用1表示相邻,0表示不相邻;对于带权图,存储权值
	InfoPtr *info;	//与弧或边的相关信息
}ArcNode,AdjMatrix[MaxSize][MaxSize];
//图的类型定义
typedef struct{
	VertexType vex[MaxSize];	//用于存储顶点
	AdjMatrix arc;		//邻接矩阵,存储边或弧的信息
	int vexnum,arcnum;	//顶点数和边(弧)的数目
	GraphKind kind;		//图的类型
}MGraph;
//记录从顶点集合U到V-U的代价最小的边的数组定义
typedef struct{
	VertexType adjvex;
	VRType lowcost;
}closeedge[MaxSize];
//在顶点向量中查找顶点v,找到返回在向量的序号,否则返回-1
int LocateVertex(MGraph N,VertexType v){
	int i;
	for(i=0;i<N.vexnum;++i)
		if(strcmp(N.vex[i],v)==0)
			return i;
	return -1;
}
//采用邻接矩阵表示法创建有向网N
void CreateGraph(MGraph *N){
	int i,j,k,w,InfoFlag,len;
	char s[MaxSize];
	VertexType v1,v2;
	printf("请输入有向网N的顶点数,弧数,弧的信息(是:1,否:0): ");
	scanf("%d,%d,%d",&(*N).vexnum,&(*N).arcnum,&InfoFlag);
	printf("请输入%d个顶点的值(<%d个字符):\n",N->vexnum,MaxSize);
	for(i=0;i<N->vexnum;++i)	//保存网的各个顶点
		scanf("%s",N->vex[i]);
	for(i=0;i<N->vexnum;i++)	//初始化邻接矩阵
		for(j=0;j<N->vexnum;j++){
			N->arc[i][j].adj=INFINITY;
			N->arc[i][j].info=NULL;	//弧的信息初始化为空
		}
		printf("请输入%d条弧的弧尾 弧头 权值(以空格作为间隔): \n",N->arcnum);
		for(k=0;k<N->arcnum;k++){
			scanf("%s%s%d",v1,v2,&w);	//输入两个顶点和弧的权值
			i=LocateVertex(*N,v1);
			j=LocateVertex(*N,v2);
			N->arc[i][j].adj=w;
			if(InfoFlag){		//如果弧包含其它信息
				printf("请输入弧的相关信息: ");
				gets(s);
				len=strlen(s);
				if(len){
					N->arc[i][j].info=(char *)malloc((len+1)*sizeof(char));
					strcpy(N->arc[i][j].info,s);
				}
			}
		}
		N->kind=DN;		//图的类型为有向网
}
//销毁网N
void DestroyGraph(MGraph *N){
	int i,j;
	for(i=0;i<N->vexnum;i++)		//释放弧的相关信息
		for(j=0;j<N->vexnum;j++)
			if(N->arc[i][j].adj!=INFINITY)	//如果存在弧
				if(N->arc[i][j].info!=NULL){	//如果弧有相关信息,释放该信息所占用空间
					free(N->arc[i][j].info);
					N->arc[i][j].info=NULL;
				}
				N->vexnum=0;	//将网的顶点数置为0
				N->arcnum=0;	//将网的弧的数目置为0
}
//
void DisplayGraph(MGraph N){
	int i,j;
	printf("有向网具有%d个顶点%d条弧,顶点依次是: ",N.vexnum,N.arcnum);
	for(i=0;i<N.vexnum;++i)		//输出网的顶点
		printf("%s ",N.vex[i]);
	printf("\n有向网N的:\n");			//输出网N的弧
	printf("序号i=");
	for(i=0;i<N.vexnum;i++)
		printf("%8d",i);
	printf("\n");
	for(i=0;i<N.vexnum;i++)
	{
		printf("%8d",i);
		for(j=0;j<N.vexnum;j++)
			printf("%8d",N.arc[i][j].adj);
		printf("\n"); 
	}
}
//将lowcost的最小值的序号返回
int MiniNum(closeedge edge,MGraph G){
	int i=0,j,k,min;
	while(!edge[i].lowcost)
		i++;
	min=edge[i].lowcost;//第一个不为0的值
	k=i;
	for(j=i+1;j<G.vexnum;j++)
		if(edge[j].lowcost>0&&edge[j].lowcost<min){	//将最小值对应的序号赋值给k
			min=edge[j].lowcost;
			k=j;
		}
	return k;
}
//利用普里姆算法求从第u个顶点出发构造网G的最小生成树T
void Prim(MGraph G,VertexType u){
	int i,j,k;
	closeedge closedge;
	k=LocateVertex(G,u);	//k为顶点u对应的序号
	for(j=0;j<G.vexnum;j++){	//数组初始化
		strcpy(closedge[j].adjvex,u);
		closedge[j].lowcost=G.arc[k][j].adj;
	}
	closedge[k].lowcost=0;		//初始时集合U只包括顶点u
	printf("无向网的最小生成树的各条边分别是:\n");
	for(i=1;i<G.vexnum;++i){	//选择剩下的G.vexnum-1个顶点
		k=MiniNum(closedge,G);	//k为与U中顶点相邻接的下一个顶点的序号
		printf("(%s-%s)\n",closedge[k].adjvex,G.vex[k]); //输出生成树的边
		closedge[k].lowcost=0;	//第k顶点并入U集
		for(j=0;j<G.vexnum;++j)
			if(G.arc[k][j].adj<closedge[j].lowcost){	//新顶点加入U集后重新将最小边存入到数组
				strcpy(closedge[j].adjvex,G.vex[k]);
				closedge[j].lowcost=G.arc[k][j].adj;
			}
	}
}
void main(){
	MGraph N;
	printf("创建一个无向网:\n");
	CreateGraph(&N);
	DisplayGraph(N);
	Prim(N,"A");	
	DestroyGraph(&N);
	system("pause");
}
技术分享

版权声明:本文为博主原创文章,未经博主允许不得转载|Copyright ©2011-2015,Supernatural, All Rights Reserved.

_DataStructure_C_Impl:图的最小生成树

标签:数据结构

原文地址:http://blog.csdn.net/williamfan21c/article/details/47411877

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!