【数据结构与算法基础】最短路径问题

前言

数据结构,一门数据处理的艺术,精巧的结构在一个又一个算法下发挥着他们无与伦比的高效和精密之美,在为信息技术打下坚实地基的同时,也令无数开发者和探索者为之着迷。

也因如此,它作为博主大二上学期最重要的必修课出现了。由于大家对于上学期C++系列博文的支持,我打算将这门课的笔记也写作系列博文,既用于整理、消化,也用于同各位交流、展示数据结构的美。

此系列文章,将会分成两条主线,一条“数据结构基础”,一条“数据结构拓展”。“数据结构基础”主要以记录课上内容为主,“拓展”则是以课上内容为基础的更加高深的数据结构或相关应用知识。

欢迎关注博主,一起交流、学习、进步,往期的文章将会放在文末。


说起图论算法,最经典的莫过于最短路径了。他永远是图论入门难以绕开的经典问题,也常常是学习图论遇到的容易卡住的难点。

说起最短路径,那首先研究的对象就是两点间的路径,它要有起点和终点。图中两个连通结点之间至少存在一条路径,最短路径就是其中权值和最小的路径。

算法中对权值定义可以很广泛,他可以是点权,也可以是边权,也可能多关键字的权重…总之不论权值如何定义,重要的只是权值和能够被表示出来且能够被比较。但在本文中,我们讨论的只有边权,且权值为正数的正权图。

这篇文章,我们探讨的最短路径分为两种:单源最短路径任意两点间最短路径
以及实现他们的两种经典算法:dijkstra算法和floyd算法

单源最短路径

单源最短路径,是指从一点出发到图中其他所有点的最短路径。

通常,只要求出到各点的最短路径长度。
有时,也会要求打印出最短路径。

例如:对于如下图
在这里插入图片描述

从源点1出发到其他节点的最短路径及距离为:

2 : 1 , 3 , 2 3 2:1,3,2\quad3 2:1,3,23
3 : 1 , 3 1 3:1,3\quad1 3:1,31
4 : 1 , 3 , 4 5 4:1,3,4\quad5 4:1,3,45
5 : 1 , 3 , 5 6 5:1,3,5\quad6 5:1,3,56
6 : 1 , 3 , 5 , 6 7 6:1,3,5,6\quad7 6:1,3,5,67

求解单源最短路径,可行的算法有很多,下面来介绍一种非常经典的算法:dijkstra算法

迪杰斯特拉(dijkstra)算法

dijkstra算法的核心思想是将全部结点分成两个集合,一个是已知最短路的集合 A A A,剩下的是未知最短路的集合 B B B,同时记录每个节点到源点的最短距离 d i s dis dis

约定:源点到自身的最短距离为0,即 d i s s = 0 dis_s = 0 diss=0。无路径的两点间的距离为无穷大。

算法步骤如下:

  • 一开始,已知最短路的集合中仅有源点一个元素。且仅记录与源点直接相连的节点的距离 d i s dis dis,其余结点默认为无穷大
  • 每次从 B B B中找出一个距离最短的结点 k k k,加入集合 A A A
  • 使用结点 k k k更新源点到 B B B中结点的最短距离,即是否经过 k k k到该结点比先前到该结点的方案更优
  • 重复上述过程,直至所有结点都加入结合 A A A
  • 最短路径长度就是结点的 d i s dis dis

对于上图,将每一次挑选节点的过程中 d i s dis dis用表格画出来就是:
在这里插入图片描述
在编写算法之前,有必要先来说明一下图的存储。有关图的存储方式,可以参考这篇博文

下面的算法中,存储方式都采用数组模拟的邻接表的方式。最短路径使用数组dis进行存储;

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值