Dijkstra算法是用来求取单项图最短路径的算法
在生活中常用于路由算法、地图导航、交通规划等场景
Dijkstra最短路径是计算机科学中一个重要的图论算法,用于在图中找到从起始顶点到其他所有顶点的最短路径。
该算法基于贪心策略,逐步从起始顶点到其他顶点的最短路径。
具体实现步骤:
- 创建一个数组用来记录起始点(我们假设为点A),记录点A到其他节点的位置,初始化为无穷大。
- 创建一个数组用于记录节点是否已经被访问,同意初始化为false
- 假设起始点到自身的距离设为0
- 遍历该节点的所有邻居节点,更新起始点到邻居节点的距离。
最终得到起始点到其他所有节点的最短距离
在计算机中,图一般使用邻接表或者邻接矩阵的存储方式,图中的节点一般抽象成一个数字(即下表或者是索引)
Dijkstra算法可以看作是BFS算法的拓展,BFS常用于无权图的遍历,Dijkstra可以作用于加权的图(权一定是正数值)
根据上文所述 需要定义三个数组
二维数组 grapg[][]用来表示有向加权图,
一维数组 visited[] 表示节点是不是被访问过 定义为bool类型 初始化为false
一维数组 dist[] 表示从起点到顶点i的最短路径长度 初始化为无穷大 dist[start] = 0
1.从dist[]中找到当前未被标记的dist[i]的最小顶点u,更改visit[i]=true
2.遍历所有跟u相邻的顶点v,如果visited[v] = flase 如果从start到u再到v的路径长度小于dist[v],更新dist[v]=dist[u]+w(u,v),w(u,v)为边(u,v)的权值。
一直重复1和2步骤 直到所有顶点都已被标记
代码实现如下:
//
// Created by 20654 on 24-9-24.
// dijkstra算法
//
#include <stdio.h>
#include <stdbool.h>
#define size 1000 // 定义图的最大节点数
#define max 1000000000 // 定义最大值
int n, m, s, e; // 节点数, 有向线段数, 起点, 终点
int graph[size][size]; // 图的邻接矩阵
int dist[size]; // 起点到各点的最短距离
bool visited[size]; // 记录节点是否被访问过
// Dijkstra算法实现函数,通过起点计算到图中各节点的最短路径
void dijkstra(int s) {
// 初始化距离和访问状态
for (int i = 1; i <= n; i++) {
dist[i] = graph[s][i];
visited[i] = false;
}
// 遍历所有节点: 看看是否从起始点先经过i,再由i到终点权值会小一点
for (int i = 1; i <= n; i++) {
int min = max, u = -1;
//遍历&比较 => 找到未访问节点中距离起点最近的节点
for (int j = 1; j <= n; j++) {
if (dist[j] < min && !visited[j]) {
u = j;
min = dist[j]; //可以用i=1的情况来理解,找到离原点最近的一个节点
}
}
if (u == -1) return; // 若未找到可达节点,退出循环
visited[u] = true; // 标记节点u为已访问
// 更新起点到各节点的距离
for (int v = 1; v <= n; v++) {
//从起始点先到u再到v的路径 < 原先记录的从原点到v的路径 && u,v之间有通路
if (dist[v] > dist[u] + graph[u][v] && !visited[v] && graph[u][v] != max) {
//v尚未访问过
dist[v] = dist[u] + graph[u][v];
}
}
}
}
// 主程序入口函数,初始化图的信息,并调用Dijkstra算法
int main(void) {
// 硬编码图的节点数,有向线段数,起点,终点
n = 5; // 例如5个节点
m = 7; // 例如7条有向线段
s = 1; // 起点
e = 5; // 终点
// 初始化图的邻接矩阵
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= n; j++) {
graph[i][j] = i == j ? 0 : max;
}
}
// 手动设置有向线段的起点、终点和权重
graph[1][2] = 10;
graph[1][3] = 5;
graph[1][4] = 9;
graph[2][4] = 6;
graph[2][5] = 8;
graph[3][4] = 7;
graph[4][5] = 7;
dijkstra(s); // 调用Dijkstra算法求最短路径
printf("最短的距离为: %d", dist[e]); // 输出起点到终点的最短距离
return 0;
}
有向图如下