广度优先遍历与最短路径

广度优先遍历从某个顶点 v 出发,首先访问这个结点,并将其标记为已访问过,然后顺序访问结点v的所有未被访问的邻接点 {vi,..,vj} ,并将其标记为已访问过,然后将 {vi,...,vj} 中的每一个节点重复节点v的访问方法,直到所有结点都被访问完为止。

我们可以分为三个步骤:

  • (1)使用一个辅助队列 q,首先将顶点 v 入队,将其标记为已访问,然后循环检测队列是否为空。
  • (2)如果队列不为空,则取出队列第一个元素,并将与该元素相关联的所有未被访问的节点入队,将这些节点标记为已访问。
  • (3)如果队列为空,则说明已经按照广度优先遍历了所有的节点。

下图所示,右边蓝色表示从 0 开始遍历节点的顺序,下面是记录距离 0 的距离,可知广度优先遍历能求出无权图的最短路径。

下面用代码展示如何用广度优先遍历方式完成遍历,并且查询到最短路径。我们在上一小节代码的基础上增加一全局变量 ord 数组,记录路径中节点的次序。ord[i] 表示 i 节点在路径中的次序。同时构造函数做出相应调整,在遍历相邻节点时 每访问一个未被访问的节点进行 ord[i] = ord[v] + 1记录距离。邻接表的广度优先遍历时间复杂度为 O(V+E),邻接矩阵的时间复杂度为O(V^2)。

...
// 构造函数, 寻路算法, 寻找图graph从s点到其他点的路径
public ShortestPath(Graph graph, int s){// 算法初始化G = graph;assert s >= 0 && s < G.V();visited = new boolean[G.V()];from = new int[G.V()];ord = new int[G.V()];for( int i = 0 ; i < G.V() ; i ++ ){visited[i] = false;from[i] = -1;ord[i] = -1;}this.s = s;// 无向图最短路径算法, 从s开始广度优先遍历整张图LinkedList<Integer> q = new LinkedList<Integer>();q.push( s );visited[s] = true;ord[s] = 0;while( !q.isEmpty() ){int v = q.pop();for( int i : G.adj(v) )if( !visited[i] ){q.push(i);visited[i] = true;from[i] = v;ord[i] = ord[v] + 1;}}
}
...

查看从 s 点到 w 点的最短路径长度,若从 s 到 w 不可达,返回-1。

...
public int length(int w){assert w >= 0 && w < G.V();return ord[w];
}
...

Java 实例代码

src/runoob/graph/ShortestPath.java 文件代码:

package runoob.graph;import runoob.graph.read.Graph;import java.util.LinkedList;
import java.util.Stack;
import java.util.Vector;/*** 广度优先遍历与最短路径*/
public class ShortestPath {// 图的引用private Graph G;// 起始点private int s;// 记录dfs的过程中节点是否被访问private boolean[] visited;// 记录路径, from[i]表示查找的路径上i的上一个节点private int[] from;// 记录路径中节点的次序。ord[i]表示i节点在路径中的次序。private int[] ord;// 构造函数, 寻路算法, 寻找图graph从s点到其他点的路径public ShortestPath(Graph graph, int s){// 算法初始化G = graph;assert s >= 0 && s < G.V();visited = new boolean[G.V()];from = new int[G.V()];ord = new int[G.V()];for( int i = 0 ; i < G.V() ; i ++ ){visited[i] = false;from[i] = -1;ord[i] = -1;}this.s = s;// 无向图最短路径算法, 从s开始广度优先遍历整张图LinkedList<Integer> q = new LinkedList<Integer>();q.push( s );visited[s] = true;ord[s] = 0;while( !q.isEmpty() ){int v = q.pop();for( int i : G.adj(v) )if( !visited[i] ){q.push(i);visited[i] = true;from[i] = v;ord[i] = ord[v] + 1;}}}// 查询从s点到w点是否有路径public boolean hasPath(int w){assert w >= 0 && w < G.V();return visited[w];}// 查询从s点到w点的路径, 存放在vec中public Vector<Integer> path(int w){assert hasPath(w) ;Stack<Integer> s = new Stack<Integer>();// 通过from数组逆向查找到从s到w的路径, 存放到栈中int p = w;while( p != -1 ){s.push(p);p = from[p];}// 从栈中依次取出元素, 获得顺序的从s到w的路径Vector<Integer> res = new Vector<Integer>();while( !s.empty() )res.add( s.pop() );return res;}// 打印出从s点到w点的路径public void showPath(int w){assert hasPath(w) ;Vector<Integer> vec = path(w);for( int i = 0 ; i < vec.size() ; i ++ ){System.out.print(vec.elementAt(i));if( i == vec.size() - 1 )System.out.println();elseSystem.out.print(" -> ");}}// 查看从s点到w点的最短路径长度// 若从s到w不可达,返回-1public int length(int w){assert w >= 0 && w < G.V();return ord[w];}
}

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

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

相关文章

Runloop解析

RunLoop 前言 ​ 本文介绍RunLoop的概念&#xff0c;并使用swift和Objective-C来描述RunLoop机制。 简介 ​ RunLoop——运行循环&#xff08;死循环&#xff09;&#xff0c;它提供了一个事件循环机制在程序运行过程中处理各种事件&#xff0c;例如用户交互、网络请求、定…

HT97226 免输出电容立体声耳机放大器的应用与曲线

HT97226应用&#xff1a; ・耳机 ・多媒体音频接口 ・机顶盒 ・ 蓝光/DVD播放器 ・LCD电视 ・音频消费电子产品 HT97226应用图于曲线&#xff1a; HT97226是一款差分输入/单端输入、可直接输出驱动的耳机放大器。5V供…

网络渗透测试(认识)

ARP协议 逻辑地址变成物理地址 32bit的IP地址变换成48bit的mac地址 ARP两个字节&#xff08;0x0806&#xff09; ARP解析协议 每一个主机都有ARP高速缓存&#xff0c;此缓存中记录了最近一段时间的内其他IP地址与其MAC地址的对应关系 如果本机想与某台主机通信&#xff0c;首先…

Azure Machine Learning - 创建Azure AI搜索服务

目录 准备工作查找 Azure AI 搜索产品/服务选择订阅设置资源组为服务命名选择区域选择层创建服务配置身份验证扩展服务何时添加第二个服务将多个服务添加到订阅 Azure AI 搜索是用于将全文搜索体验添加到自定义应用的 Azure 资源&#xff0c;本文介绍如何创建Azure AI搜索服务 …

5.前端--CSS-基本概念【2023.11.26】

1. CSS 语法规范 CSS 规则由两个主要的部分构成&#xff1a;选择器以及一条或多条声明。 属性和属性值之间用英文“:”分开 多个“键值对”之间用英文“;”进行区分 选择器 : 简单来说&#xff0c;就是选择标签用的。 声明 &#xff1a;就是改变样式 2.CSS引入方式 按照 CSS 样…

网络运维与网络安全 学习笔记2023.11.26

网络运维与网络安全 学习笔记 第二十七天 今日目标 NAT场景与原理、静态NAT、动态NAT PAT原理与配置、动态PAT之EasyIP、静态PAT之NAT Server NAT场景与原理 项目背景 为节省IP地址和费用&#xff0c;企业内网使用的都是“私有IP地址” Internet网络的组成设备&#xff0c…

【办公软件】电脑开机密码忘记了如何重置?

这个案例是家人的电脑&#xff0c;已经使用多年&#xff0c;又是有小孩操作过的&#xff0c;所以电脑密码根本不记得是什么了&#xff1f;那难道这台电脑就废了吗&#xff1f;需要重新装机吗&#xff1f;那里面的资料不是没有了&#xff1f; 为了解决以上问题&#xff0c;一般…

MySQL 高可用架构

MySQL 是实际生产中最常用的数据库&#xff0c;生产环境数据量极为庞大&#xff0c;对性能和安全要求很高&#xff0c;单机的 MySQL 是远远达不到的&#xff0c;所以必须搭建一个主从复制架构&#xff0c;同时可以基于一些工具实现高可用架构&#xff0c;在此基础上&#xff0c…

基于Java SSM框架+Vue实现药品保健品购物网站项目【项目源码+论文说明】计算机毕业设计

基于java的SSM框架Vue实现药品保健品购物网站演示 摘要 随着社会的发展&#xff0c;社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 ssm药源购物网站&#xff0c;主要的模块包括两个用户&#xff0c;管理员权限&#xff1a;用…

Re55:读论文 Entities as Experts: Sparse Memory Access with Entity Supervision

诸神缄默不语-个人CSDN博文目录 诸神缄默不语的论文阅读笔记和分类 论文名称&#xff1a;Entities as Experts: Sparse Memory Access with Entity Supervision 模型名称&#xff1a;Entities as Experts (EaE) ArXiv网址&#xff1a;https://arxiv.org/abs/2004.07202 本文…

leetcode:有效的括号

题目描述 题目链接&#xff1a;20. 有效的括号 - 力扣&#xff08;LeetCode&#xff09; 题目分析 题目给了我们三种括号&#xff1a;&#xff08;&#xff09;、{ }、[ ] 这里的匹配包括&#xff1a;顺序匹配和数量匹配 最优的思路就是用栈来解决&#xff1a; 括号依次入栈…

2 时间序列预测入门:GRU

0 论文地址 GRU 原论文&#xff1a;https://arxiv.org/pdf/1406.1078v3.pdf GRU&#xff08;Gate Recurrent Unit&#xff09;是循环神经网络&#xff08;RNN&#xff09;的一种&#xff0c;可以解决RNN中不能长期记忆和反向传播中的梯度等问题&#xff0c;与LSTM的作用类似&a…