Dijkstra 算法-利用优先队列Priority Queue实现的Lazy版本

本文详细介绍了如何使用Dijkstra算法结合优先队列(PriorityQueue)来寻找图中从源点到各顶点的最短路径。通过定义Dijkstra_Node结构体,dist和prev数组以及visited数组,实现了路径记录和更新。在C语言中,利用minPriorityQueue,逐步遍历并更新最短距离,同时处理重复顶点的情况。最后,提供了算法的头文件、函数实现和测试代码。

Dijkstra 算法,优先队列法

如前所述,Dijkstra算法是图论中非常重要的算法之一。前一篇对严蔚敏《数据结构》进行梳理和代码实现,严版的算法中利用P[v][w] ,D[w] 和 final[v] 对源点和各个之间的最短距离的路径,长度和访问标记进行记录,最终求得SSSP(single source shortest path)路径。

本文主要介绍如何利用Priority Queue(PQ)队列,求得源点至各个顶点的最短距离。对于Priority Queue的实现,这里不做赘述,有兴趣的可以参考网上的相关文章介绍,本文主要用到min Priority Queue,队列的顶点永远保持最小值的元素。

实现算法之前,我们需要抽象几个数据结构体,首先需要定义Priority Queue的堆中储存的数据对象类型,我们这里采用记录顶点序列号和到达此顶点的最短距离两个记录。

a) Dijkstra_Node 结构体

/**
@param -index indicates the visiting vertex order
@param -dist indcates the current min distance from source to here
**/
typedef struct Dijkstra_Node
{
   
   
    int index;
    int dist;
} Dijkstra_Node;

b) dist[] 数组,dist将记录源点到此点的最短距离,过程中需要不断利用贪心思想,最总求得某个顶点的最小dist[w]。
c) prev[]数组,记录某个顶点的前置顶点,便于后续遍历时,能找到完整的最短路径,否则就只能得到最小值或最短距离,无法获取其具体路径。
d) visited[]数组,这个数组属于在邻接图中有定义,如果访问过,标记为1

利用William提供的示意图,对PQ为基础的Dijkstra进行说明。

  • 首先需要对dist数组进行初始,推定各个点距离源点S的距离为INT_MAX(机器中的最大整数),然后把pre[]赋值为-1,表明各个顶点还暂未前置顶点,最后把visited[]初始化为0,表明各节点还未开始访问。
  • 然后以源点为起起始点,遍历其可达的顶点,如果可达顶点还未访问,那么就需要加入到PQ列表中去
  • 在PQ中出栈最小的(index, dist)序列,重复以上步骤。
    在这里插入图片描述
    在这里插入图片描述
    过程中可能存在存在一类情况,就是到达某个顶点有多个PQ记录,这时候可以对重复的顶点记录(dist不同)进行skip处理,因为相对某个顶点的最小距离遍历后,再取相同顶点的较大距离,不会产生更好的结果。
    在这里插入图片描述
    上述遍历完成(1,3)之后,就没有必要再遍历(1,4),因为对于顶点1,后续出栈的距离,至少大于等于前面出栈的距离,也即4>3。所以对(1,4)直接出栈不需要进行后续任何操作。

由于Priority Queue已经采用C语言实现,自然而然本算法也沿用C语言进行后续的继续操作,包括结构体和函数的定义实现。

a) 头文件说明,本头文件中已经包含了PQ的实现,读者可以自己编写PQ,编写过程中,可以预定义Heap中的对象,在实际应用中可以重新定义(ShortestPath.h)。

/**
 * @file ShortestPath.h
 * @author your name (you@domain.com)
 * @brief 
 * @version 0.1
 * @date 2023-02-09
 * 
 * @copyright Copyright (c) 2023
 * 
 */

#ifndef SHORTESTPATH_H
#define SHORTESTPATH_H
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<limits.h>
#include "../00_introduction/Status.h"
#include "../02_Adjacent_List_Graph/AdjacentListGraph.c"

typedef struct Dijkstra_Node
{
   
   
    int index;
    int dist;
} Dijkstra_Node;

typedef Dijkstra_Node priority_queue_element;

#include "../11_PriorityQueue/PriorityQueue.c"

/**
 * @brief Use priority que
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值