数据结构 最短路径问题

最短路径问题:已知一个文本文件中保存了一个有向网图的顶点信息序列和弧信息序列,符号#”表示顶点信息序列结束。每条弧信息包括弧尾和弧头的编号以及弧的权值(顶点编号为负数表示结束,相邻数据间用空白符分隔)。要求:从键盘输入保存有向网图信息的文件标识符,再输入起点和终点编号,求出起点到终点的最短路径,并显示从起点到终点的顶点编号、权值以及路径长度。

比如起点为2,终点为6,显示“2(10)7(20)4(50)8(30)6:110”表示起点到终点的最短路径由弧<2,7><7,4><4,8><8,6>组成,权值分别为10205030,路径长度为110

注意,最短路径问题还是需要自己去写一个文本文件才可以打开看!

嘿嘿 还是用两种方式写出来的呢

第一种

#include
#include
#define N 100
#define verflag '#'
typedef char VertexType;
#define MAXCOST 1000000
typedef char VertexType;
typedef int EdgeType;

typedef struct
{ VertexType vexs[N];
  EdgeType edges[N][N];
    int n,e;
}MMGraph;

int CreateMMGraph(MMGraph *G)
{ char filename[100],ch;
    FILE*fp;
    int i,j;
  EdgeType w;
    G->n=G->e=0;
    puts("请输入保存有向网图顶点和边信息的文件标识符");
    gets(filename);
  if((fp=fopen(filename,"r"))==NULL)return 0;
   while((ch=fgetc(fp))!=verflag)
   G->vexs[G->n++]=ch;
   for(i=0;in;i++)
   for(j=0;jn;j++)
	  G->edges[i][j]=0;
  fscanf(fp,"%d %d %d",&i,&j,&w);
  while(i>-1)
  { G->edges[i-1][j-1]=w;
    G->e++;
	fscanf(fp,"%d %d %d",&i,&j,&w);
  }
    fclose(fp);
	return 1;
}

void ShortestPath(MMGraph*G,int P[N],int D[N],int s,int t)
{ int final[N]={0},i,j,k,min,pre,stack[N],top=-1;
     if(s==t)return ;
	 for(i=0;in;i++)
		 for(j=0;jn;j++)
			 G->edges[i][j]=G->edges[i][j]?G->edges[i][j]:MAXCOST;
		 for(i=0;in;i++)
		 {  D[i]=G->edges[s][i];
		    P[i]=s;
		 }
		 final[s]=1;  P[s]=-1;
		 for(i=0;in;i++)
		 {   if(i==s)continue;
		      min=MAXCOST+1;
              for(k=0;kn;k++)
				  if(final[k]==0 && D[k]n;k++)
					  if(final[k]==0 && D[j]+G->edges[j][k]edges[j][k];
						  P[k]=j;
					  }
		 }
		 if(i==G->n)
			 printf("编号%d的顶点到编号%d的顶点无通路\n",s+1,t+1);
		 else
		 { stack[++top]=i=t;
           while((i=P[i])!=-1)
			stack[++top]=i;
			pre=stack[top--];
		 printf("编号%d的顶点到编号%d的顶点的最短路径为\n",s+1,t+1);
		 printf("%d",pre+1);
		 while(top>-1)
		 {  i=stack[top--];
		    printf("(%d)%d",G->edges[pre][i],i+1);
		    pre=i; 
		 }
		 printf(":%d\n",D[t]);
	}
}

void main()
{  MMGraph *G;
   int P[N],D[N],s,t;
   G=(MMGraph*)malloc(sizeof(MMGraph));
   if(!CreateMMGraph(G))
   { puts("文件打开失败!");
      return ;
   }
   printf("请输入源点和终点的编号");
   scanf("%d%d",&s,&t);
   ShortestPath(G,P,D,s-1,t-1);
}

第二种方式

#include
#include
#define MAXCOST 100000
#define N 100
#define verflag '#'
typedef char VertexType;
typedef int EdgeType;


typedef struct
{
	VertexType vexs[N];
	EdgeType edges[N][N];
	int n,e;
} MMGraph;

int CreateMMGraph(MMGraph *G)
{
	char filename[100],ch;
	FILE* fp;
	int i,j;
	EdgeType w;
	G->n=G->e=0;
	puts("请输入保存有向网图顶点和边信息的文件标识符");
	gets(filename);
	if((fp=fopen(filename,"r"))==NULL)return 0;
	while((ch=fgetc(fp))!=verflag)
		G->vexs[G->n++]=ch;
	for(i=0; in; i++)
		for(j=0; jn; j++)
			G->edges[i][j]=0;
	fscanf(fp,"%d %d %d",&i,&j,&w);
	while(i>-1)
		{
			G->edges[i-1][j-1]=w;
			G->e++;
			fscanf(fp,"%d %d %d",&i,&j,&w);
		}
	fclose(fp);
	return 1;
}


void ShortestPath(MMGraph*G,int P[N],int D[N],int s,int t)
{
	int final[N]= {0},i,j,k,min,pre,stack[N],top=-1;
	if(s==t)return ;
	for(i=0; in; i++)
		for(j=0; jn; j++)
			G->edges[i][j]=G->edges[i][j]?G->edges[i][j]:MAXCOST;
	for(i=0; in; i++)
		{
			D[i]=G->edges[s][i];
			P[i]=s;
		}
	final[s]=1;
	P[s]=-1;
	for(i=0; in; i++)
		{
			if(i==s) continue;
			min=MAXCOST+1;
			for(k=0; kn; k++)
				{
					if(final[k]==0&&D[k]n; k++)
				if(final[k]==0&&D[j]+G->edges[j][k]edges[j][k];
						P[k]=j;
					}
		}
	if(i==G->n)
		printf("编号%d的顶点到编号%d的顶点无通路\n",s+1,t+1);
	else
		{
			stack[++top]=i=t;
			while((i=P[i])!=-1)
				stack[++top]=i;
				pre=stack[top--]; 
			printf("编号为%d的顶点到编号%d的顶点的最短路径为\n",s+1,t+1);
			printf("%d",pre+1);
			while(top>-1)
				{
					i=stack[top--];
					printf("(%d)%d",G->edges[pre][i],i+1);
					pre=i;
				}
			printf(":%d\n",D[t]);
		}
}

void main()
{
	MMGraph *G;
	int tree[N],cost[N],i;
	int P[N],D[N],s,t;
	G=(MMGraph*)malloc(sizeof(MMGraph));
	if(!CreateMMGraph(G))
		{
			puts("文件打开失败!");
			return ;
		}
	printf("请输入源点和终点的编号\n");
	scanf("%d %d",&s,&t);
	ShortestPath(G,P,D,s-1,t-1);
}

输出结果为

数据结构 最短路径问题_第1张图片

你可能感兴趣的:(数据结构)