【数据结构与算法】【算法思想】Dijkstra算法

图的两种搜索算法,深度优先搜素和广度优先搜索。这两种算法主要是针对无权图的搜索算法。针对有权图,也就是图中的每条边都有一个权重,该如何计算两点之间的最短路径?最短路径算法(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算法等。

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/424688.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第二十三期:程序员节Keep被曝突然裁员300多人,60%是开发和运营

社交健身App “Keep”突然裁员超300人&#xff0c;而且是在1024程序员节。此次被裁的人员中&#xff0c;大约有60%的人是开发和运营&#xff0c;补偿方案为N1。 作者&#xff1a;三言财经 10月24日脉脉有多条消息称&#xff0c;社交健身App “Keep”突然裁员超300人&#xff0…

542. 01 Matrix

输入&#xff1a;元素值为0或者1的矩阵。 输出&#xff1a; 每个元素距离0的最近距离是多少。 规则&#xff1a;相邻单元格的距离是1&#xff0c;相邻是指上下左右4个方向。 分析&#xff1a;这类似于学习课程安排&#xff0c;可以从元素值为0的单元开始沿4个方向遍历。matrix[…

第二十四期:管理 | 成功领导远程IT团队的7个技巧

管理虚拟工作环境需要各种真实世界的技能和工具。以下是激发创造力和生产力的策略。为了在日益缺乏人才和竞争激烈的IT世界中取得成功&#xff0c;越来越多的企业开始依赖于地理上分散的劳动力。 作者&#xff1a;John Edwards 管理虚拟工作环境需要各种真实世界的技能和工具…

310. Minimum Height Trees

输入&#xff1a;包含n个节点的无向图。n&#xff1a;表示从0到n-1&#xff0c;n个节点。edges&#xff1a;int数组&#xff0c;是从一个节点到另外一个节点。但是没有方向。 输出&#xff1a;以哪些节点为根节点&#xff0c;具有最小高度的树&#xff0c;返回这些根节点。 规则…

计算获取最小值和最大值

比如&#xff0c;在下面的销售业绩中&#xff0c;统计业务员的销售业绩中最大值和最小值。 下面是业务数据&#xff1a; CREATE TABLE [dbo].[SalesPerformance]([ID] [int] IDENTITY(1,1) NOT NULL,[Salesman] NVARCHAR(30) NOT NULL,[OrderDate] [DATE] NULL,[Sell] DECIM…

第二十五期:知乎用Go替代Python,说明了啥

众所周知&#xff0c;知乎早在几年前就将推荐系统从 Python 转为了 Go。于是乎&#xff0c;一部分人就说 Go 比 Python 好&#xff0c;Go 和 Python 两大社区的相关开发人员为此也争论过不少&#xff0c;似乎&#xff0c;谁也没完全说服谁。 作者&#xff1a;hello架构 大概每…

[Leetcode][第106题][JAVA][ 从中序与后序遍历序列构造二叉树][分治][递归]

【问题描述】[中等] 【解答思路】 public class Solution {public TreeNode buildTree(int[] inorder, int[] postorder) {int inLen inorder.length;int postLen postorder.length;// 特判if (inLen ! postLen) {throw new RuntimeException("输入错误");}return …

第二十六期:英国建设下一代IOT基础设施的历史机遇和挑战

无论未来物联网发展的中心在哪里&#xff0c;都会带来一笔巨大的财富。但许多地区面临的真正障碍是缺乏可用的光纤基础设施来形成回程网络。接下来看一看全光纤在英国的推广情况。 作者&#xff1a;风车云马编译 世界各地的市政当局都在呼吁制定支持5G的基础设施计划。这些基…

[Leetcode][第889题][JAVA][根据前序和后序遍历构造二叉树][分治][递归]

【问题描述】[中等] 【解答思路】 copyOfRange class Solution {public TreeNode constructFromPrePost(int[] pre, int[] post) {if(prenull || pre.length0) {return null;}return dfs(pre,post);}private TreeNode dfs(int[] pre,int[] post) {if(prenull || pre.length0)…

第二十七期:Deepfake视频正在快速传播,也许区块链能够阻止这波“瘟疫”

“假新闻”一词已经成为当下的热门话题&#xff0c;而Deepfake(即看似真实&#xff0c;但实为伪造的视频操纵行为)则会进一步加剧民众与媒体之间的不信任危机。 作者&#xff1a;佚名来源 “假新闻”一词已经成为当下的热门话题&#xff0c;而Deepfake(即看似真实&#xff0c;…

POJ 1276 完全背包

Sample Input 735 3 4 125 6 5 3 350 633 4 500 30 6 100 1 5 0 1 735 0 0 3 10 100 10 50 10 10 Sample Output 735 630 0 0题意&#xff1a;你的银行卡里有 cash 元&#xff0c;而ATM机里有 n 种面值的钱&#xff0c;n行每种钱的数量和面值。  问 最多能从这台AT…

[Leetcode][第117题][JAVA][填充每个节点的下一个右侧节点指针][BFS]

【问题描述】[中等] 【解答思路】 1. 层次遍历 public Node connect(Node root) {if (root null)return root;Queue<Node> queue new LinkedList<>();queue.add(root);while (!queue.isEmpty()) {//每一层的数量int levelCount queue.size();//前一个节点Node …

第二十八期:Java线程池的四种用法与使用场景

线程池的作用主要是为了提升系统的性能以及使用率。文章刚开始就提到&#xff0c;如果我们使用最简单的方式创建线程&#xff0c;如果用户量比较大&#xff0c;那么就会产生很多创建和销毁线程的动作&#xff0c;这会导致服务器在创建和销毁线程上消耗的性能可能要比处理实际业…

php连接mysql遇到的问题: (HY000/1130) 和 [caching_sha2_password]

说明一下我的mysql是安装在虚拟机上的 所以遇到的第一个问题就是访问问题 解决&#xff1a; update user set host % where user root; 重启mysql服务 试了很多方法&#xff0c;也找了很多方法只有这个可行。 问题2&#xff0c; 解决&#xff1a; https://www.cnblogs.com/un…

847. Shortest Path Visiting All Nodes(一)

输入&#xff1a;一个无向图&#xff0c;各个节点的标签是0、1、2…N-1。graph[i][j]表示从节点i到节点j有一条边。 输出&#xff1a;返回每个节点都访问一遍需要的最少步骤。 规则&#xff1a;各个节点可以重复访问。 分析&#xff1a;  如果可以知道从每个节点开始&#xf…

第二十九期:程序员们该如何破局!

我是实打实的程序员一枚&#xff0c;身为一个过来人&#xff0c;我觉得有必要说几点针对程序员们的破局思维&#xff0c;希望能解决不少人的迷茫与困惑。 作者&#xff1a;stormzhang 新读者可能不知道&#xff0c;老读者都晓得&#xff0c;虽说现在转身做了自媒体&#xff0c…

[Leetcode][第75题][JAVA][颜色分类][双(三)指针][计数排序]

【问题描述】[中等] 【解答思路】 1. 三指针 时间复杂度&#xff1a;O(N) 空间复杂度&#xff1a;O(1) class Solution {public void sortColors(int[] nums) {int n nums.length;int p0 0, p2 n - 1;for (int i 0; i < p2; i) {while (i < p2 && nums[i] …

第三十期:程序员报告:男性占比超87% 北京月薪12184元最高

1024“程序员节”&#xff0c;58同城招聘研究院发布程序员行业大数据报告显示&#xff0c;程序员男性占比高达87.29%。 作者&#xff1a;朝晖 1024“程序员节”&#xff0c;58同城招聘研究院发布程序员行业大数据报告显示&#xff0c;程序员男性占比高达87.29%&#xff0c;北…

[Leetcode][LCP 19][JAVA][秋叶收藏集][动态规划]

【问题描述】[中等] 【解答思路】 1. 动态规划 时间复杂度&#xff1a;O(N) 空间复杂度&#xff1a;O(N) class Solution {public int minimumOperations(String leaves) {if (leaves null || leaves "") { // 排除 不合法参数情况return 0;}int length leave…

第三十一期:QQ for Linux 复活,微信 for Linux 还远吗?

网友通过分析龙芯处理器的生态支持计划与近期 QQ for Linux 支持 MIPS 架构的事实&#xff0c;结合当前国产自主研发的大背景&#xff0c;认为距离微信 for Linux 的发布也不远了。 10 月 24 日晚间&#xff0c;腾讯突然发布了沉寂多年的 QQ for Linux 新版本&#xff0c;引起了…