图的两种搜索算法,深度优先搜素和广度优先搜索。这两种算法主要是针对无权图的搜索算法。针对有权图,也就是图中的每条边都有一个权重,该如何计算两点之间的最短路径?最短路径算法(Shortest Path Algorithm)。

一:算法解析
最优问题包含三个:最短路线,最少用时,最少红绿灯。
1,解诀软件开发中的实际问题,最重要的一点就是建模,也就是将复杂的场景抽象成具体的数据结构。
2,图的表达能力强,可以将求解的最短路径问题转化为:在一个有向有权图中,求两个顶点间的最短路径。
3,要解决这个问题,有个非常经典的算法,最短路径算法,更准确的叫:单源最短路径算法(一个顶点到一个顶点)。提到最短路径算法,最出名的莫过于DijKstra算法。

Dijkstra算法

算法结构


public class Graph { // 有向有权图的邻接表表示private LinkedList<Edge> adj[]; // 邻接表private int v; // 顶点个数public Graph(int v) {this.v = v;this.adj = new LinkedList[v];for (int i = 0; i < v; ++i) {this.adj[i] = new LinkedList<>();}}public void addEdge(int s, int t, int w) { // 添加一条边this.adj[s].add(new Edge(s, t, w));}private class Edge {public int sid; // 边的起始顶点编号public int tid; // 边的终止顶点编号public int w; // 权重public Edge(int sid, int tid, int w) {this.sid = sid;this.tid = tid;this.w = w;}}// 下面这个类是为了dijkstra实现用的private class Vertex {public int id; // 顶点编号IDpublic int dist; // 从起始顶点到这个顶点的距离public Vertex(int id, int dist) {this.id = id;this.dist = dist;}}
}

实现算法


// 因为Java提供的优先级队列,没有暴露更新数据的接口,所以我们需要重新实现一个
private class PriorityQueue { // 根据vertex.dist构建小顶堆private Vertex[] nodes;private int count;public PriorityQueue(int v) {this.nodes = new Vertex[v+1];this.count = v;}public Vertex poll() { // TODO: 留给读者实现... }public void add(Vertex vertex) { // TODO: 留给读者实现...}// 更新结点的值,并且从下往上堆化,重新符合堆的定义。时间复杂度O(logn)。public void update(Vertex vertex) { // TODO: 留给读者实现...} public boolean isEmpty() { // TODO: 留给读者实现...}
}public void dijkstra(int s, int t) { // 从顶点s到顶点t的最短路径int[] predecessor = new int[this.v]; // 用来还原最短路径Vertex[] vertexes = new Vertex[this.v];for (int i = 0; i < this.v; ++i) {vertexes[i] = new Vertex(i, Integer.MAX_VALUE);}PriorityQueue queue = new PriorityQueue(this.v);// 小顶堆boolean[] inqueue = new boolean[this.v]; // 标记是否进入过队列vertexes[s].dist = 0;queue.add(vertexes[s]);inqueue[s] = true;while (!queue.isEmpty()) {Vertex minVertex= queue.poll(); // 取堆顶元素并删除if (minVertex.id == t) break; // 最短路径产生了for (int i = 0; i < adj[minVertex.id].size(); ++i) {Edge e = adj[minVertex.id].get(i); // 取出一条minVetex相连的边Vertex nextVertex = vertexes[e.tid]; // minVertex-->nextVertexif (minVertex.dist + e.w < nextVertex.dist) { // 更新next的distnextVertex.dist = minVertex.dist + e.w;predecessor[nextVertex.id] = minVertex.id;if (inqueue[nextVertex.id] == true) {queue.update(nextVertex); // 更新队列中的dist值} else {queue.add(nextVertex);inqueue[nextVertex.id] = true;}}}}// 输出最短路径System.out.print(s);print(s, t, predecessor);
}private void print(int s, int t, int[] predecessor) {if (s == t) return;print(s, predecessor[t], predecessor);System.out.print("->" + t);
}


用 vertexes 数组,记录从起始顶点到每个顶点的距离(dist)。起初,我们把所有顶点的 dist 都初始化为无穷大(也就是代码中的Integer.MAX_VALUE)。
把起始顶点的 dist 值初始化为 0,然后将其放到优先级队列中。我们从优先级队列中取出 dist 最小的顶点 minVertex,然后考察这个顶点可达的所有顶点(代码中的 nextVertex)。如果 minVertex 的 dist 值加上 minVertex 与 nextVertex 之间边的权重 w 小于 nextVertex 当前的 dist 值,也就是说,存在另一条更短的路径,它经过 minVertex 到达 nextVertex。那我们就把 nextVertex 的 dist 更新为 minVertex 的 dist 值加上 w。然后,我们把 nextVertex 加入到优先级队列中。重复这个过程,直到找到终止顶点 t 或者队列为空。
以上就是 Dijkstra 算法的核心逻辑。除此之外,代码中还有两个额外的变量,predecessor 数组和 inqueue 数组
predecessor 数组的作用是为了还原最短路径,它记录每个顶点的前驱顶点。最后,我们通过递归的方式,将这个路径打印出来。打印路径的 print 递归代码我就不详细讲了,这个跟我们在图的搜索中讲的打印路径方法一样。如果不理解的话,你可以回过头去看下那一节。
inqueue 数组是为了避免将一个顶点多次添加到优先级队列中。我们更新了某个顶点的 dist 值之后,如果这个顶点已经在优先级队列中了,就不要再将它重复添加进去了。

Dijkstra算法的时间复杂度

O(E*log V),E表示边的个数,V表示元素个数不会超过顶点的个数
5,Dijkstra最短路径算法,实际上最短路径算法还有很多,比如Bellford算法,Floyd算法等。

笔记整理来源: 王争 数据结构与算法之美

【数据结构与算法】【算法思想】Dijkstra算法相关推荐

  1. 【数据结构】图(最短路径Dijkstra算法)的JAVA代码实现

    最短路径的概念 最短路径的问题是比较典型的应用问题.在图中,确定了起始点和终点之后,一般情况下都可以有很多条路径来连接两者.而边或弧的权值最小的那一条路径就称为两点之间的最短路径,路径上的第一个顶点为 ...

  2. 数据结构——图——迪杰斯特拉(Dijkstra )算法

    数据结构--图--迪杰斯特拉(Dijkstra )算法 这是一个按路径长度递增的次序产生最短路径的算法.它的思路大体是这样的. 比如说要求图7-7-3中顶点v0到顶点v1的最短距离,没有比这更简单的了 ...

  3. 数据结构最短路径例题_编程小白暑期进阶笔记45-C语言数据结构与算法最短路径和dijkstra算法...

    最短路径 算法特点: 迪科斯彻算法使用了广度优先搜索解决赋权有向图或者无向图的单源最短路径问题,算法最终得到一个最短路径树.该算法常用于路由算法或者作为其他图算法的一个子模块. 算法思路: Dijks ...

  4. 遍历所有点的最短路径python_图遍历算法之最短路径Dijkstra算法

    一.最短路径问题(shortest path problem) 最短路径问题是图论研究中一个经典算法问题,旨在寻找图中两节点或单个节点到其他节点之间的最短路径.根据问题的不同,算法的具体形式包括: 确 ...

  5. 自动寻路算法python_关于Dijkstra算法和其他的一些图算法(Johnson, Floyd-Warshall, A*)解决最短路径问题的方法的Python实现。...

    这篇文章其实主要想说的是如何解决最短路径的问题. 其实最短路径问题,我们在生活中都在不知不觉的使用.比如我们在上网的时候,互联网传输采用了各种各样的数据包路由方法.这些路由算法都在幕后工作. 还有一些 ...

  6. 求一个任意实数c的算术平方根g的算法设计思想_算法复习第四篇——贪心法

    公元2020年5月5日,距离算法考试仅剩4天. 一.知识归纳 1.设计思想 只根据当前已有的信息就做出选择,而且一旦做出了选择,将来无论如何都不能更改 不从整体最优考虑,所做的选择只是在某种意义上的局 ...

  7. python实现ks算法_Python实现Dijkstra算法

    Dijkstra算法 迪杰斯特拉算法是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法.是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题.迪杰斯特拉算法主要 ...

  8. 【爬虫、算法】基于Dijkstra算法的武汉地铁路径规划!

    作者:牧小熊,华中农业大学,Datawhale原创作者 前言 最近爬取了武汉地铁线路的信息,通过调用高德地图的api 获得各个站点的进度和纬度信息,使用Dijkstra算法对路径进行规划. 1.数据爬 ...

  9. java 有向图 最短路径算法_java使用Dijkstra算法实现单源最短路径

    单源最短路径问题,即在图中求出给定顶点到其它任一顶点的最短路径.在弄清楚如何求算单源最短路径问题之前,必须弄清楚最短路径的最优子结构性质. 一.最短路径的最优子结构性质 该性质描述为:如果P(i,j) ...

  10. 图论-全源最短路径-对比Floyd算法与暴力Dijkstra算法

    题目 输入顶点数N,有向边数M,接下来M行输入格式为u,v,w分别代表两个顶点u,v和两点之间边的权值w.输出全源最短路径 输入样例: 6 8 0 1 1 0 3 4 0 4 4 1 3 2 2 5 ...

最新文章

  1. git clone 出现错误 Could not resolve host: github.com
  2. VLAN是什么?VLAN交换机端口类型有哪些?—Vecloud微云
  3. win7 计算机库 桌面,【备忘】win7下再硬盘安装win7(桌面库和家庭组图标删除)...
  4. LightOj 1078 Basic Math
  5. datatable如何生成级联数据_如何把Excel表数据批量生成条形码
  6. 新网卡不能绑定“旧”IP故障的解决
  7. windows和linux中搭建python集成开发环境IDE——如何设置多个python环境
  8. mysql索引抽密度_使用python脚本从abaqus输出数据库获取元素密度
  9. Django学习之Cookie和Session
  10. Tomcat的安装及配置。
  11. 用SegNet进行室内布局语义分割
  12. excel单元格做下拉列表以及改变下拉列表的字体
  13. 餐厅点餐系统设计思路
  14. excel美化技巧-持续更新
  15. 高等数学学习笔记——第二十九讲——罗尔定理与拉格朗日中值定理
  16. 离散小波matlab程序,三维离散小波变换matlab实现.pdf
  17. linux支持xfs文件系统,LINUX下使用XFS文件系统
  18. 把16 支球队随机分为4 个组。
  19. PHP实现微信公众平台开发---提升篇(网页授权接口)
  20. 【.net】Ueditor中图片上传和图片回显路径的设置

热门文章

  1. SharePoint 跨域还原网站一则
  2. Linux 服务器远程控制三剑客Telnet、SSH 和 VNC 之 VNC
  3. rocketmq 初探(四)
  4. 从使用传统Web框架到切换到Spring Boot后的总结
  5. java des对称加密_JAVA加密解密DES对称加密算法
  6. 使用spring ResponseEntity处理http响应
  7. 14 | 排序优化:如何实现一个通用的、高性能的排序函数?
  8. Spring 集成web环境
  9. java平面_java知识点整理
  10. pycharm自带python环境_Pycharm安装+python安装+环境配置