最短路径c语言_最短路径的Dijkstra算法

本文介绍了Dijkstra算法,一种用于解决图最短路径问题的经典算法。通过举例和C语言实现,阐述了算法的工作原理和步骤,并提供了一个简单的C语言程序模板。此外,还提及了其他求解最短路径的算法,鼓励读者进一步学习比较。
摘要由CSDN通过智能技术生成

点击上方蓝字,关注我们

95935f4e39ac18506a1e32498f07288b.png

道路千万条,安全第一条。

行车不规范,亲人两行泪。

假如你是刘启,带领救援队去杭州地下城送火石,车载导航被moss远程控制了,你翻出19年泛黄的地图……

不识路啊,这咋整啊?

ce8206569c15fc7b702bfafc78103c59.gif

在平时我们使用导航时,在已知起点和终点的情况下,导航总能在复杂的道路中为我们找到一条最短的道路。在这个过程中,我们可以将道路简化抽象成一个由点与点之间的连线构成的图。

每个路口都可以看作是图的顶点,顶点之间的连线代表实际中两路口间的道路,而图的边的权则代表道路的长度。若图的边有一个指向,则此图为有向图,且若A→B,则代表有路从A到B。这样,导航做的事其实就是给定图中两点,找到一条连接两点的最短路。

上述问题即图最短路径问题,它一直是图论里面一个重要问题。用于解决这个问题的算法有很多种。今天我们给大家介绍一种非常经典的算法——Dijkstra算法。

这个算法是由图灵奖得主Dijkstra提出的,得到了广泛的应用。这种有着30年历史的算法是一种典型的贪婪算法。简单来说,这个算法的核心思想就是在每一步都选取最短的一条路径,不考虑之后的状况。

Dijstra算法

若给定一个图,我们想知道从点A到其它点的最短路径长度,则Dijkstra算法的具体步骤是:

1.生成一个表,表中记录了两组数据。一组是图中其它点到点A的已知最短距离d,另一种代表此距离是否即为最短距离(0代表存疑,1代表是)。表的初始数据为:若A可直接到达点C(不经过其它点),则A→C的距离为边的权,否则为∞。初始所有顶点存疑。

2.选择一个顶点X,它是表中所有存疑顶点中具有最小的d的点。然后对于X能直接到达的每个点(如Y),考虑路径A→X→Y的长度,若小于表中Y的d,则更新此数据。最后顶点X的数据0更新为1。

3.如此遍历,当没有存疑顶点时(均为1),整个算法执行完毕,则所有顶点到已知顶点A的最小距离都被找到了。

ce8206569c15fc7b702bfafc78103c59.gif

举个栗子(๑• . •๑)

已知如图

64be9eebed526446c1d47a346e54938e.png

这是初始化时的情况

fb01c9d14a8fca9780b8fa30e4767258.png

假设我们以V1为起始顶点,则表的初始数据如下

99ad606a3f0e6b7cd38cc8ed03f3e809.png

接下来访问距离最短的V3,发现一条V1→V3→V4的路径,更新V4的d

99ad606a3f0e6b7cd38cc8ed03f3e809.png

访问V5(存疑的顶点中v最小的),此时到V6有一条V1→V5→V6的路径,长度为90,所以更新V6的d,同时V4也要更新

2605632b6a95b0b0a99e936887bbe76f.png

访问V4,再次更新V6

86188cc77327fb45b86d8f7585767197.png

访问V6

26abe1ad77d7cd6e6514fd80de6af8bf.png

最后因为以V2位终点的边,所以算法结束,得出了其他点到V1的最短距离。

ce8206569c15fc7b702bfafc78103c59.gif

那么问题来了,为什么Dijkstra算法是有效的,其每一步的意义何在呢?

其实算法的原理很简单:

每一步都是从选定的点的一个向外的路径探索过程。则在一次更新完成后,此时存疑的顶点中的d最小的顶点到选定点的最短路径即为最短。

若不是这样,则对于其最短路径,它从选定点出发,必会经过探索到的路径,但此段路径的长度已经不小于上述路径了。

C语言实现

那么,如何用C语言实现这个算法呢?

a03bf5ee85a021eb66c313587d976e5f.png 34758411a9305b6405eebe501c457bb4.png f900c3a348e076bf8c97484d67146319.png 4f078fe014ba6a4482f38f28a0825040.png ab82b18768c34b85ec905220809fb45a.png

简单来说,上述程序的功能是:

● 将顶点按0、1…顺序编号。

● 第一行输入顶点个数与边的数量。

● 下面每行代表一条边,有三个数字,分别代表边的起点、终点、长度。

● 最后一行输入起始顶点的编号。

● 则输出是按字典序的起始顶点到其它顶点的最短距离(输出-1代表两点间没有路径)。

ce8206569c15fc7b702bfafc78103c59.gif

再举个栗子(´・ω・`)

已知如图

0d37ca9345be4d9c1a09d72dc0bdf4b6.png

用邻接矩阵的方式输入这个图

7e25e779356261d6cb2fa434ff778213.png

8是顶点个数,11是边的条数,最后的3是以3为起点

3b6ceeaa2ed66d7a64138e483232287b.png

最后以字典序输出了其余顶点到3的距离,其中-1表示没有从起点到这个顶点的路。

ce8206569c15fc7b702bfafc78103c59.gif

大家可以试试在上述程序的基础上扩充些内容,使能够输给定点到其它点的最短路径长度及其相应的路径。

当然最短路径问题还有其它种种算法(Floyd算法、Bellman-Ford算法等),可以自行了解比较各种算法的优劣与核心原理哟٩(๑> v

ce8206569c15fc7b702bfafc78103c59.gif

最后悄咪咪说句:

祝大家开学快乐(❁´ω`❁)*✲゚*~

撰写:李唯贤

排版:T桐子yo

cd0ac1d57b7750d2665d073a06effd65.gif

数学建模,封印解除!

400f1eb68daa63382d66377e35085f06.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值