最短路径-迪杰斯特拉(C语言简单实现)

本文介绍了迪杰斯特拉(Dijkstra)算法的基本思想和简单实现,用于解决网图中最短路径问题。通过逐步求解每个顶点到源点的最短路径,最终得到整个图的最短路径。此外,还提及了弗洛伊德(Floyd)算法在求所有顶点间最短路径的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最短路径

本文参考自《大话数据结构》,网上有很多关于迪杰斯特拉和弗洛伊德算法的描述和图解,大家都可以去看看,这里就不赘述,只是对迪杰斯特拉算法做简单实现。

在网图和非网图中,最短路径的含义是不同的。由于非网图它没有边上的权值,所谓的最短路径,其实就是指两顶点之间经过的边数最少的路径;而对于网图来说,最短路径,是指两顶点之间经过的边上权值之和最少的路径,并且我们称路径上的第一个顶点是源点,最后一个顶点是终点

迪杰斯特拉(Dijkstra)算法

这个算法的思路就是:求整个图的最短路径(最优解,不一定唯一),转化为求局部最优解,以下面这图为例:

最短路径-迪杰斯特拉示例

求a到d的最短路径,我们肉眼可以看出最短路径是走a->b->d或者a->c->d,但这只是简单的情况,那么假如有几十个点的情况,怎么做呢?

我们可以将复杂的问题简单化,分步求解:

最短路径-迪杰斯特拉示例2

复杂的不会求,那么这个够简单了吧,a到b的距离,只有1条边,很明显就是1

最短路径-迪杰斯特拉示例3

那这个呢?a到d的最短距离,a到d有2条路可以走,分别是a->b->da->d,也就是1+24做比较。

那么n个结点呢?一样的,就是每次都拿到源结点,然后找到所有能到达目的结点的路径,然后比较所有路径的长度;因为我们一开始并不知道走哪条路能到达目的结点,所以我们需要遍历整个图所有结点;而计算到目的结点的最优解,就变成了每一次都计算出到v(v指任意结点)结点的最短路径,每一次的局部最短路径(最优解),合起来就变成了最终的最短路径(最优解)。这就是迪杰斯特拉算法的灵魂。

#define MAXVEX 9
#define INFINITY 65535
typedef int Pathmatirx[MAXVEX];	//用于存储最短路径下标的数组
typedef int ShortPathTable[MAXVEX];	//用于存储到各点最短路径的权值和
/* Dijkstra算法,求有向图G的v0顶点到其余顶点v最短路径P[v]及带权长度D[v],P[v]的值为前驱顶点下标,D[v]表示v0到v的最短路径长度和 */
void ShortestPath_Dijkstra(MGraph G, int v0, Pathmatirx *P, ShortPathTable *D){
   
   
	int v, w, k, min;
	int final[MAXVEX];	//final[w] = 1表示求得顶点v0到vw的最短路径
	for(v=0;v<G.numVertexes;v++){
   
   		//初始化数据
		final[v] = 0;	//全部顶点初始化为未知最短路径状态
		(*D)[v] = G.matirx[v0][v];	//将与v0点有连线的顶点加上权值
		(*P)[v] = 0;	//初始化路径数组P为0
	}
	(*D)[v0] = 0;	//v0至v0路径为0
	final[v0] = 1;	//v0至v0不需要求路径
	/* 开始主循环,每次求得v0到某个v顶点的最短路径 */
	for(v=1;v<G.numVertexes;v++){
   
   
		min = INFINITY;	//当前所知离v0顶点的最近距离
		for(w=0;w<G.numVertexes;w++){
   
   	//寻找离v0最近的顶点
			if(!final[w] && (*D)[w]<min){
   
   
				k = w;
				min = (*D)[w];	//w顶点离v0顶点更近
			}
		}
		final[k] = 1;	//将目前找到的最近的顶点置为1
		for(w=0;w<G.numVertexes;w++){
   
   	//如果经过v顶点的路径比现在这条路径的长度短的话
			if(!final[w] && (min+G.matirx[k][w] < 
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值