算法概述
Dijkstra 算法用于求算单源点最短路径问题,即给定源点,求算该点到其他各点的最短距离。
源点到任意点的最短路径建立在源点到该点前驱的最短路径上。以源点为中心,向外一步一步扩展,直到所有点的最短路径都被找出。
此外,该算法要求任意两点间的权值不可为负值。
情景
思路
一开始,我打算先实现Dijkstra 算法,所以直接将图的邻接矩阵、前驱数组这些设为全局变量(二维数组的传参我给忘了),而且将邻接矩阵直接初始化,减少调试的成本。
设源点为V0,求算V0到各终点的最短距离。
初始化最短距离数组(Distance)、前驱数组(Pioneer)、状态数组(S);
Dijikstra 算法核心:
1.从当前点开始更新最短距离数组(如果当前点是源点则不用更新,因为已经在初始化方法中更新了);
2.找出最短距离数组中权值最小的结点,并认为该点为已找到;
3.以该点作为当前点,回到第一步。
打印路径和最短距离;
代码一
#include<stdio.h>
#include<stdlib.h>
#define N 6 //记录图中点的数量
#define MAX 1000
#define START 0 //起点
/*
邻接矩阵
寝室 0; 偏门 1; A广场 2; 大门 3; B广场 4; A 5;
点与点间有临接路径,则值为两点间权值;
点与点间没有临接路径,或为同点,则值为MAX;
*/
float Graph[N][N] = {
{ MAX,200,MAX,250,MAX,MAX },
{ MAX,MAX,MAX,150,MAX,MAX },
{ MAX,50,MAX,MAX,MAX,250 },
{ MAX,MAX,MAX,MAX,60,MAX },
{ MAX,MAX,300,MAX,MAX,MAX },
{ MAX,MAX,250,MAX,350,MAX }
};
/*
记录最短距离
例如 V0 -> V2 -> V4 存在最短路径, 且V0 -> V2 = 20, V2 -> V4 = 40,
则 Distance[4] = 60;
Distance 数组元素初始化为START 行的数据;
Distance[START] = 0;
*/
float Distance[N];
/*
记录前驱
例如 V0 -> V2 -> V4 ,则Pioneer[4] = 2;
Pioneer数组元素初始化全为 -1;
Pioneer[起点] 永为 -1, 起点到起点没前驱;
*/
int Pioneer[N];
/*
记录起点与该点之间是否已找到最短路径;
找到: 1, 没找到: 0;
S 数组元素除起点外全部初始化为 0;
S[起点] 永为 1;
*/
int S[N];
/*************************************************/
/*
初始化 Distance、Pioneer、S 数组
*/
void initialize() {
//初始化Distance 数组
for (int i = 0;i < N;i++) {
Distance[i] = Graph[START][i];
}
Distance[START] = 0;
//初始化Previous 数组
for (int i = 0;i < N;i++) {
if (Distance[i] != 0 && Distance[i] != MAX) {
Pioneer[i] = START;
}
else {
Pioneer[i] = -1;
}
}
//初始化S 数组
for (int i = 0;i < N;i++) {
S[i] =