一、算法功能:
给定一个出发点(单源点)和一个有向网G=(V, E)
, 求出源点到其它各顶点之间的最短路径。
二、算法思想:
(1)把图中顶点集合分成两组,第一组为集合S,存放已求出其最短路径的顶点,第二组为尚未确定最短路径的顶点集合是V-S
(令W=V-S),其中V为网中所有顶点集合。
(2)按最短路径长度递增的顺序逐个把W中的顶点加到S中,直到S中包含全部顶点,而W为空。
(3)在加入的过程中,总保持从源点v到S中各顶点的最短路径长度不大于从源点v到W中任何顶点的最短路径长度。
(4)此外,每个顶点对应一个距离,S中的顶点的距离就是从v到此顶点的最短路径长度,W中的顶点的距离从v到此顶点只包括S中的顶点为中间顶点的当前最短路径长度。
三、实现步骤:
(1)初始时,S只包含源点,S={v},v的距离为0。U包含除v外的其他顶点,U中顶点的距离为顶点的权或∞ 。
(2)从U中选取一个距离最小的顶点k,把k加入到S中。
(3)以k 作为新考虑的中间点,**修改**U中各顶点的距离。
(4)重复步骤(1)、(2)直到所有顶点都包含在S中。
四、举例:
求v0到其它各点的最短路径:
答:最短路径为(V0,V2,V4,V3,V5)
五、算法实现:
/*======================================================
* Copyright (C) 2017
*
* 文件名称:dijkstra.c
* 创 建 者:ZhouYang
* 创建日期:2017年06月01日
* 描 述:dijkstra算法实现
*
====================================================*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAX_INT 32767
int main(void)
{
int i,j,k;
int vertexLen, edgeLen;
int len_S,len_U;
int min,weight,sum=0;
char initial_node,final_node;
char node,mid;
char startVertex, endVertex;
printf("please input vertex's number:");
scanf("%d",&vertexLen);
printf("please input edge's number:");
scanf("%d",&edgeLen);
int graph[vertexLen][vertexLen];
char route[vertexLen];
char S[vertexLen],U[vertexLen];
int node_min[vertexLen];
for(i=0;i<vertexLen;i++)
for(j=0;j<vertexLen;j++){
if(i==j)
graph[i][j] = 0;
else
graph[i][j] = MAX_INT;
}
for(i=0; i<edgeLen; i++){
printf("please input the %d edge's start vertex name (vertex name from a to %c):",i+1,'a'+vertexLen-1);
scanf(" %c",&startVertex);
printf("please input the %d edge's end vertex name (vertex name from a to %c):",i+1,'a'+vertexLen-1);
scanf(" %c",&endVertex);
printf("please input this edge's weight:");
scanf("%d",&weight);
graph[startVertex-'a'][endVertex-'a'] = weight;
}
for(i=0;i<vertexLen;i++)
node_min[i]=MAX_INT;
printf("Input initial node:");
scanf(" %c",&initial_node);
printf("Input final node:");
scanf(" %c",&final_node);
S[0]=initial_node;
j=0;
for(i=0;i<vertexLen;i++)
{
if(initial_node != 'a'+i)
U[j++]='a'+i;
}
len_S=1;
len_U=4;
node_min[initial_node-'a']=0;
node=initial_node;
for(i=0;i<vertexLen-1;i++)
{
for(j=0;j<vertexLen;j++)
{
if(node_min[j]>graph[node-'a'][j]+node_min[node-'a'])
{
node_min[j]=graph[node-'a'][j]+node_min[node-'a'];
}
}
min=MAX_INT;
for(j=0;j<len_U;j++)
{
if(min>node_min[U[j]-'a'])
{
min=node_min[U[j]-'a'];
mid=U[j];
k=j;
}
}
while(k<len_U)
{
U[k]=U[k+1];
k++;
}
len_U--;
len_S++;
S[len_S-1]=mid;
node=mid;
}
mid=final_node;
k=0;
route[k++]=mid;
while(1)
{
for(i=0;i<vertexLen;i++)
{
if(mid!='a'+i)
{
if(node_min[mid-'a']-node_min[i]==graph[i][mid-'a'])
{
sum += node_min[mid-'a']-node_min[i];
mid='a'+i;
route[k++]=mid;
break;
}
}
}
if(mid == initial_node)
break;
}
for(i = k-1;i>0;i--)
printf("%c-->",route[i]);
printf("%c",final_node);
printf("\nweight sum is %d",sum);
return 0;
}
图如下:
运行结果: