Dijkstra算法

一,Dijkstra算法说明

1.举例说明

我们之前的prim和kruskal都是求最小生成树的n-1条边

而现在迪杰斯特拉是求单源点到其他顶点的最短距离

a.如下图当我们把每个点之间的路径当做绳子,最开始所有点平放在桌面上,把a提起来时顶点离开桌面的顺序取决于其到A的距离

b.下图离开桌面的顺序为A,B,D,C,E

c.当所有顶点离开桌面时,绷直的绳子就是他到其他顶点的最短路径

2.代码逻辑

首先我们需要三个数组

a.dist是源点到其他顶点的距离

b.path是记录到该顶点前经过的顶点

c.check描述该点是否被访问过

我们图结构如下,假如单源点为0,标记mark[0]为1,更新0的邻接点的dist和path

更新dist和path:假如该点未被激活过且新的路径长度比当前更短就覆盖当前路径长度并更新path,否则不更新

找与当前节点边最短的邻接点为待激活点,重复上述单源点的操作

二,Dijkstra代码实现

1.头文件中的接口

cpp 复制代码
//
// Created by 27893 on 2025/8/4.
//

#ifndef DIJKSTRA_H
#define DIJKSTRA_H
#include "../MatrixGraph/MatrixGraph.h"
void DijkstraMGraph(MGraph *graph, int start, int *dist, int *path);

void showShortPath(const int*path,int sum,int pos);
#endif //DIJKSTRA_H

2.将头文件中的接口一一实现

cpp 复制代码
//
// Created by 27893 on 2025/8/4.
//

#include "Dijkstra.h"

#include <stdio.h>
#include <stdlib.h>

void DijkstraMGraph(MGraph *graph, int start, int *dist, int *path) {
	//1.初始化激活第一个顶点
	int*mark=malloc(sizeof(int)*graph->nodeNum);
	for (int i=0;i<graph->nodeNum;++i) {
		dist[i]=graph->edges[start][i];
		mark[i]=0;
		if (graph->edges[start][i]<INF) {
			path[i]=start;
		}else {
			path[i]=-1;
		}
	}
	dist[start]=0;
	path[start]=-1;
	mark[start]=1;
	//2.核心循环
	for (int i=0;i<graph->nodeNum-1;++i) {
		int mini=INF,k=0;
		for (int j=0;j<graph->nodeNum;++j) {
			//3.找到最小值为待激活点
			if (mark[j]==0&&dist[j]<mini) {
				mini=dist[j];
				k=j;
			}
		}
		mark[k]=1;
		//4.激活,更新dist和path
		for (int j=0;j<graph->nodeNum;++j) {
			if (mark[j]==0&&dist[k]+graph->edges[k][j]<dist[j]) {
				dist[j]=dist[k]+graph->edges[k][j];
				path[j]=k;
			}
		}
	}
	free(mark);
}

void showShortPath(const int *path, int sum, int pos) {
	int*stack=malloc(sizeof(int)*sum);
	int top=-1;
	//1.倒序入栈
	while (path[pos]!=-1) {
		stack[++top]=pos;
		pos=path[pos];
	}
	stack[++top]=pos;
	//2.顺序出栈,遍历
	while (top!=-1) {
		printf("%d\t",stack[top--]);
	}
	printf("\n");
	free(stack);
}

3.测试代码是否有bug

cpp 复制代码
//
// Created by 27893 on 2025/8/4.
//
#include <stdio.h>
#include <stdlib.h>

#include "Dijkstra.h"
void setup(MGraph*graph) {
	const char *names[] = {"0", "1", "2", "3", "4", "5", "6",};
	initMGraph(graph, names, sizeof(names) / sizeof(names[0]), 1, INF);
	addMGraph(graph, 0, 1,4);
	addMGraph(graph, 0, 2, 6);
	addMGraph(graph, 0, 3, 6);
	addMGraph(graph, 1, 2, 1);
	addMGraph(graph, 1, 4, 7);
	addMGraph(graph, 2, 4, 6);
	addMGraph(graph, 2, 5, 4);
	addMGraph(graph, 3, 5, 5);
	addMGraph(graph, 3, 2, 2);
	addMGraph(graph, 4, 6, 6);
	addMGraph(graph, 5, 4, 1);
	addMGraph(graph, 5, 6, 8);
}
int main() {
	MGraph graph;
	setup(&graph);
	int*dist=malloc(sizeof(int)*graph.nodeNum);
	int*path=malloc(sizeof(int)*graph.nodeNum);
	if (dist==NULL||path==NULL) {
		return -1;
	}
	DijkstraMGraph(&graph,0,dist,path);
	printf("from #0 to #5:dist:%d\n",dist[5]);
	showShortPath(path,graph.nodeNum,5);
	printf("from #0 to #6:dist:%d\n",dist[6]);
	showShortPath(path,graph.nodeNum,6);
	free(dist);
	return 0;
}
相关推荐
NfN-sh4 分钟前
计数组合学7.12( RSK算法的一些推论)
笔记·学习·算法
ikkkkkkkl15 分钟前
LeetCode:15.三数之和&&18.四数之和
c++·算法·leetcode
屁股割了还要学1 小时前
【数据结构入门】链表
c语言·开发语言·数据结构·c++·学习·算法·链表
Mr数据杨1 小时前
数据与模型优化随机森林回归进行天气预测
算法·随机森林·回归
chen1111 小时前
有关人工智能(AI)的搜索算法(CS50)
算法
恣艺1 小时前
LeetCode 135:分糖果
算法·leetcode·职场和发展
TDengine (老段)2 小时前
TDengine 中 TDgp 中添加算法模型(异常检测)
java·大数据·数据库·算法·时序数据库·tdengine·涛思数据
2501_924748242 小时前
高密度客流识别精度↑32%!陌讯多模态融合算法在智慧交通的实战解析
大数据·人工智能·算法·目标检测·计算机视觉
WeiJingYu.2 小时前
逻辑回归的应用
算法·机器学习·逻辑回归