Dijkstra算法是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法。是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题。迪杰斯特拉算法主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。
Dijkstra算法的基本思想是以起点为中心,不断的向外扩张,直到扩张到终点。同时Dijkstra最重要的定理是:如果存在一条从i到j的最短路径(Vi.....Vk,Vj),Vk是Vj前面的一顶点。那么(Vi...Vk)也必定是从i到k的最短路径。为了求出最短路径,Dijkstra就提出了以最短路径长度递增,逐次生成最短路径的算法。譬如对于源顶点V0,首先选择其直接相邻的顶点中长度最短的顶点Vi,那么当前已知可得从V0到达Vj顶点的最短距离dist[j]=min{dist[j],dist[i]+matrix[i][j]}。
1. 更新起点的权值。
2. 寻找起点附近权值最小的点。
3. 以最短的下一点为起点,更新权值。
4. 寻找下一点中权值最小的点。
5. 又更新权值(dist[j]=min{dist[j],dist[i]+matrix[i][j]})
6. 一直循环直到扩张到终点。
下面给出我写的Dijkstra 最短路径函数。输入参数分别是(邻接矩阵,起点,终点,用于保存路径权值的数值,邻接矩阵的下标最大值+1,保存路径的数组)
void Dijkstra(int ** const topo, int start, int end, int * path_weight, int topo_size, int * path)
{
int i, j;
int *mark;
mark = (int *)malloc(sizeof(int) * topo_size);
for (i = 0; i < topo_size; i++)
{
path_weight[i] = topo[start][i];
if (topo[start][i] == Infinity)
{
path[i] = -1;
}
else
{
path[i] = start;
}
mark[i] = 0;
}
mark[start] = 1;
path_weight[start] = 0;
int next_start = start;
for (i = 0; i < topo_size; i++)
{
//找到最小的权值
int temp = Infinity;
for (j = 0; j < topo_size; j++)
{
if (mark[j] == 0 && path_weight[j] < temp)
{
temp = path_weight[j];
next_start = j;
}
}
if (next_start == end && next_start == start)
break;
mark[next_start] = 1;
for (j = 0; j < topo_size; j++)
{
if (mark[j] == 0 && topo[next_start][j] != Infinity)
{
//更新每一步的权值
if (path_weight[j] > (path_weight[next_start] + topo[next_start][j]) )
{
path_weight[j] = path_weight[next_start] + topo[next_start][j];
path[j] = next_start;
}
}
}
}
free(mark);
printf("源点%d到顶点%d路径总长度: %d \n%d",start, end, path_weight[end], end);
find(path, end);
printf("\n");
}
参考链接:
http://blog.youkuaiyun.com/longshengguoji/article/details/10756003/
http://www.cnblogs.com/dolphin0520/archive/2011/08/26/2155202.html
http://blog.163.com/cindy_19810217/blog/static/20105911820131019114612133/