您的位置:首页 > 编程语言 > C语言/C++

C语言实现图的最短路径Dijkstra算法

2017-08-01 16:02 323 查看
Dijkstra算法采用了动态规划的思想,是一个按照路径长度递增的次序产生最短路径的算法。

其中有三个重要的数组,final[w]表示下标为w的节点是否已经求得了最短路径,值为1表示已经得到。

D[w]表示下标为w的节点的最短路径权值和。

P[w]表示下标为w的节点的最短路径上前驱节点的下标值。

最终返回数组D,P,就可以得到v0节点到任意一个节点的最短路径序列和路径长度。

这里采用的是图的邻接矩阵存储结构。

以下代码在DEV C++中运行通过。

#include <stdio.h>

#define INFINITY 65535

typedef int VertexType;   //顶点是字符型
typedef int EdgeType;   //边是整型
typedef struct    //图的邻接矩阵存储结构
{

VertexType vexs[9];  //顶点向量

EdgeType edges[9][9];     //邻接矩阵

int vexnum,arcnum;    //图中当前的顶点数和边数

}MGraph;

/* 邻接矩阵的建立*/

void CreateGraph(MGraph *G)
{
int i,j,k,weight;
int ch1,ch2;

printf("请输入顶点数和边数(输入格式为:顶点数,边数):");

scanf("%d,%d",&(G->vexnum),&(G->arcnum));

printf("请输入顶点名称(输入格式为:a,b,c...):");

for(i=0;i<G->vexnum;i++)
{
getchar();
scanf("%d",&(G->vexs[i]));
}

for(i=0;i<G->vexnum;i++)
for(j=0;j<G->vexnum;j++)
if(i==j)
G->edges[i][j]=0;
else
G->edges[i][j]=INFINITY;

printf("请输入每条边对应的两个顶点名称(输入格式为:a,b):\n");

for(k=0;k<G->arcnum;k++)
{
// getchar();
printf("请输入第%d条边的两个顶点名称:",k+1);
scanf("%d,%d",&ch1,&ch2);
for(i=0;ch1!=G->vexs[i];i++);
for(j=0;ch2!=G->vexs[j];j++);
getchar();
printf("请输入第%d条边的权值:",k+1);
scanf("%d",&weight);
G->edges[i][j]=weight;
G->edges[j][i]=weight;
}
}

void ShortestPath_Dijkstra(MGraph G,int v0,int* P,int* D)
{
int v,w,k,min;
int final[9];//final[w]=1表示已经得到v0到vw的最短路径
for(v=0;v<G.vexnum;v++)
{
final[v]=0;
D[v]=G.edges[v0][v];
P[v]=0;
}
D[v0]=0;
final[v0]=1;
/*开始主循环,每次求得v0到某个v顶点的最短路径*/
for(v=1;v<G.vexnum;v++)
{
min=INFINITY;
for(w=0;w<G.vexnum;w++)
{
if(!final[w]&&D[w]<min)
{
k=w;
min=D[w];
}
}
final[k]=1;
for(w=0;w<G.vexnum;w++)
{
if(!final[w]&&(min+G.edges[k][w]<D[w]))
{
D[w]=min+G.edges[k][w];
P[w]=k;
}
}
}
}
void main()
{
MGraph G;
CreateGraph(&G);
int v0=0,j;
int P[9];
int D[9];
ShortestPath_Dijkstra(G,v0,P,D);
for(j=0;j<9;j++)
{
printf("%d,",P[j]);
}
printf("\n");
for(j=0;j<9;j++)
{
printf("%d,",D[j]);
}
}


运行结果如图所示。



求所有顶点到其他所有顶点的最短路径就是对每个顶点当作源点运行一次以上算法,这样整个算法的时间复杂度为O(n^3)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: