编制一个可以对图进行遍历和用迪杰斯特拉算法求指定顶点到其余各顶点的最短路径的程序。
实验目的
1.掌握图的基本存储方法。
2.掌握有关图的操作算法并用高级语言编程实现;
3.熟练掌握图的两种搜索路径的遍历方法。
算法描述
1)记S为已经找到的从V0出发的最短路径的终点的集合,它的初始状态为空集。那
么,从V出发到图上其余各顶点VI可能达到的最短路径的初始值为
D[i]=arcs[Locate Vex(G,V)][i].
2)选择Vj使得:
D[j]=Min{D[i] | vi不属于S} Vj就是当前求得的一条从V出发的最短路径的终点。
将j加入到S中。
3)修改从V出发到集合V—S上任意顶点Vk可达到的最短路径长度。如果:
D[j]+arcs[j][k]<D[k],则修改D[k]为D[k]=D[j]+arcs[j][k];
4)重复操作(2)(3)N-1次。由此求得从V到图上其余各顶点的最短路径是以路径长度递增的序列。
测试数据
邻接矩阵
0,INF,10,INF,30,100
INF,0,5,INF,INF,INF
INF,INF,0,50,INF,INF
INF,INF,INF,0,INF,10
INF,INF,INF,20,0,60
INF,INF,INF,INF,INF,0
注意:INF为无穷大
实验结果
1)求出vo到其余各点的最短距离。
2)打印出vo到其余各点的最短路径。
运行结果
代码实现
#include<stdio.h>
#include<malloc.h>
typedef int InfoType;
#define MAXV 100 //最大顶点个数
#define INF 32767 //INF表示无穷大
typedef struct
{
int no;//顶点编号
InfoType info;//顶点其他信息
}VertexType;//顶点类型
typedef struct
{//图的定义
int edges[MAXV][MAXV]; //邻接矩阵
int n;//顶点数
int e;//边数
VertexType vex[MAXV];//存放顶点信息
}MGraph;//图的邻接矩阵类型
void DisMat1(MGraph g);
void ppath(int path[],int i,int v);
void DisPath(int dist[],int path[],int s[],int n,int v);
void Dijkstra(MGraph g, int v);
void DisMat1(MGraph g)
{
int i,j;
for(i=0;i<g.n;i++)
{
for(j=0;j<g.n;j++)
if(g.edges[i][j]==INF)
printf("%4s","∞");
else
printf("%4d",g.edges[i][j]);
printf("\n");
}
}
void ppath(int path[],int i,int v)
{
int k;
k=path[i];
if(k==v)return;
ppath(path,k,v);
printf("%d,",k);
}
void DisPath(int dist[],int path[],int s[],int n,int v)
{
int i;
for(i=0;i<n;i++)
if(s[i]==1)
{
if(i!=v)
{
printf(" 从%d到%d的最短路径长度为:%d\t路径:",v,i,dist[i]);
printf("%d,",v);ppath(path,i,v);printf("%d\n",i);
}
}
else printf(" 从%d到%d不存在路径\n",v,i);
}
void Dijkstra(MGraph g, int v)
{
int dist[MAXV],path[MAXV];
int s[MAXV];
int mindis,i,j,u,n=g.n;
for(i=0;i<n;i++)
{
dist[i]=g.edges[v][i];//距离初始化
s[i]=0;//s[]制空
if(g.edges[v][i]<INF)//路径初始化
path[i]=v;
else
path[i]=-1;
}
s[v]=1;path[v]=0;//源点编号v放入s中
for(i=0;i<n;i++)//循环直到所有顶点的最短路径都求出
{
mindis=INF;
u=-1;
for(j=0;j<n;j++)
if(s[j]==0&&dist[j]<mindis&&dist[j]!=0)//选取不在s中且具有最小距离的顶点u
{
u=j;
mindis=dist[j];
}
if(u!=-1)
{
s[u]=1;//顶点u加入s中
for(j=0;j<n;j++)//修改不在s中的顶点的距离
if(s[j]==0)
{//v通过u到j的距离与v直接到j的距离比较
if(g.edges[u][j]<INF&&dist[u]+g.edges[u][j]<dist[j])
{
dist[j]=dist[u]+g.edges[u][j];
path[j]=u;
}
}
}
}
printf("输出最短路径:\n");
DisPath(dist,path,s,n,v);//输出最短路径
}
void main()
{
int i,j,u=0;
MGraph g;
int A[MAXV][6]=
{{0,INF,10,INF,30,100},
{INF,0,5,INF,INF,INF},
{INF,INF,0,50,INF,INF},
{INF,INF,INF,0,INF,10},
{INF,INF,INF,20,0,60},
{INF,INF,INF,INF,INF,0}};
g.n=6;g.e=8;
for(i=0;i<g.n;i++)
for(j=0;j<g.n;j++)
g.edges[i][j]=A[i][j];
printf("有向图G的邻接矩阵:\n");
DisMat1(g);
Dijkstra(g,u);
printf("\n");
}
/*
0,INF,10,INF,30,100
INF,0,5,INF,INF,INF
INF,INF,0,50,INF,INF
INF,INF,INF,0,INF,10
INF,INF,INF,20,0,60
INF,INF,INF,INF,INF,0
*/