主要思想:
迪杰斯特拉算法思想:其整体思想就是不断的找距离起始点最近的点。
我们需要两个数组,一个用来记录每个点是否已经被访问过,另一个则是记录起始点到各个点的距离,用于判断并选择距离最近的点
整个算法其实就是两个步骤:
第一步:选择距离最近的点,并访问它
第二步:更新其他没有被访问过的节点与起始点的距离
重复这两个步骤,直到所有点被访问完。
#include <stdio.h>
#include <stdbool.h>
#define INF 9999 // 表示无穷大
/*
*/
// 定义节点数的最大值
#define MAX_SIZE 100
// 计算数组大小
#define SIZE(arr) ((sizeof(arr))/(sizeof(arr[0])))
// Dijkstra算法函数
void Dijkstra(int graph[MAX_SIZE][MAX_SIZE], int n, int start) {
int dist[MAX_SIZE]; // 保存从起始节点到其他节点的最短路径
bool visited[MAX_SIZE]; // 记录节点是否已访问
// 初始化
for (int i = 0; i < n; i++) {
dist[i] = INF; // 将所有距离初始化为无穷大
visited[i] = false; // 将所有节点标记为未访问
}
dist[start] = 0; // 起始节点到自身的距离为0
// 计算最短路径
for (int count = 0; count < n - 1; count++) {
int minDist = INF;
int u;
// 选择距离起始节点最近的未访问节点
for (int v = 0; v < n; v++) {
if (visited[v] == false && dist[v] <= minDist) {
minDist = dist[v];
u = v;
}
}
visited[u] = true; // 标记节点为已访问
// 更新距离
for (int v = 0; v < n; v++) {
//首先这个节点肯定是没有被访问过,然后u到v必须要存在路径,最后就是距离的比较,
//看经过了u节点到达v节点的距离长度是否是小于当前保存的最小距离
if (!visited[v] && graph[u][v] && dist[u] + graph[u][v] < dist[v]) {
dist[v] = dist[u] + graph[u][v];
}
}
}
// 输出最短路径
printf("节点\t距离\n");
for (int i = 0; i < n; i++) {
printf("%d\t%d\n", i, dist[i]);
}
}
int main() {
int graph[MAX_SIZE][MAX_SIZE] = {
{0, 5, 2, 0},
{0, 0, 0, 3},
{0, 0, 0, 2},
{0, 0, 0, 0}
};
int n = SIZE(graph);
int start = 0; // 起始节点
Dijkstra(graph, n, start);
return 0;
}