C语言-最短路径(Dijskra算法)

本文深入解析了迪杰斯特拉算法,一种用于求解单源点最短路径的经典算法。详细介绍了算法的执行流程、核心步骤,以及如何在邻接矩阵中查找最短路径。通过具体的代码实例,展示了算法的具体实现过程。
  1. 顶点下标查找函数(LocateVex)
  2. 创建有向网(CreateDN)
  3. 打印图函数(print)
  4. 展示最短路径函数(displayPath)
  5. 查找当前最短路径函数(FindMinDist)
  6. 迪杰斯特拉算法(ShortestPath_Dijkstra)

单源点最短路径

  1. 什么叫单源点最短路径?
  • 单源点指的就是单一的起始点,那么单源点最短路径指的就是,从单一起始点到其余顶点的最短路径。
  1. 网图与非网图的单源点最短路径
  • 对于非网图而言,最短路径表示的是由起始点到终点需要经过的最少路径条数
  • 对于网图而言,最短路径表示的是由起始点到终点,所需花费的最少代价,也就是路径权值总和最小

最短路径算法

  • 对于网(带权图)而言,求两点之间的最短路径有两种算法:迪杰斯特拉(Dijkstra算法)和 弗洛伊德(Floyd算法)
  1. 单源最短路径—迪杰斯特拉算法:从一个起始点出发,到达一个终点
  2. 多源最短路径—弗洛伊德算法:求每一对顶点之间的最短路径

Prim算法与Dijskra算法的同异之处

  • 迪杰斯特拉算法处处可见普里姆算法的影子,大体上两者都是在寻找当前情况下的最短边,而不同之处在于,迪杰斯特拉算法做了路程的累加(见下代码第42-46行)
void ShortestPath_Dijkstra(MGraph *G,VertexType start)
{
   
   
	int i,j,num;
	int loc;
	int min;
	int dist[VertexMax];//最短路径长度数组 
	int path[VertexMax];//最短路径数组 
	int s[VertexMax];//代表集合S(1代表该顶点已处理,属于集合S;0代表该顶点未处理,不属于集合S,属于集合V-S) 
	
	//1.初始化dist和path数组 
	loc=LocateVex(G,start);//获取源点的下标位置 
	for(i=0;i<G->vexnum;i++)
	{
   
   
		dist[i]=G->AdjMatrix[loc][i];//初始化dist数组
		
		if(dist[i]!=MaxInt)//初始化path数组
		{
   
   
			path[i]=loc;
		}
		else
		{
   
   
			path[i]=-1;
		}	  
	} 
    
    //2.初始化S数组(s数组:代表集合S,1代表该元素属于集合S(已处理的顶点),0该元素不属于集合S(未处理的顶点)) 
    for(i=0;i<G->vexnum;i++)
	{
   
   
		s[i]=0;
	} 
	s[loc]=1;//代表起始点(源点)以处理完毕 
	num=1;
	
	//3.
	while(num<G->vexnum)
	{
   
   
		min=FindMinDist(dist,s,G->vexnum);//在dist数组中查找其对应s[i]=0,即未处理的最小值元素 
		s[min]=1;//将找到的最短边所对应的的顶点加入集合S
		
		for(i=0;i<G->vexnum;i++)//加入新的顶点后,更新dist和path数组 
		{
   
   
			if((s[i]==0)&&(dist[i]>dist[min]+G->AdjMatrix[min][i]))//路径累加
			{
   
   
				dist[i]=dist[min]+G->AdjMatrix[min][i];
				path[i]=min;
			}
		}
	    num++;	
	}    
} 

Dijskra执行流程:




(本人懒得作图,此处借用懒猫老师文图演示)

  • 算法步骤:
  1. 初始化:
    1.1 初始化dist[i]数组
    1.2 根据dist[i]数组来初始化path[i]数组
    1.3 初始化S集合,也就是初始化s[i]数组
  2. 查找后续顶点,不断地累加、更新、迭代,生成最短路径。(Dijskra算法核心部分)
    (注:迪杰斯特拉算法并不能直接生成最短路径,但是算法将最短路径信息保存在dist数组和path数组中。)

如何根据dist和path数组输出最短路径?

  1. dist数组中保存的是起始点数组下标对应顶点的路径长度(累加的结果)
  2. path数组中保存的是对应path数组下标顶点前驱顶点(前一个顶点)
  • 所以我们可以将终点带入path数组中,在一步步反推回起始点,即可得到反序最短路径
  • 此时我们再将反序最短路径放入一个数组中,在反序输出即可
  • 具体实现于函数displayPath

完整源代码

#include <stdio.h>
#include <stdlib.h>
#define VertexMax 20 
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Attract1206

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值