博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
广度优先搜索(BFS)总结及其Java实现
阅读量:4113 次
发布时间:2019-05-25

本文共 1911 字,大约阅读时间需要 6 分钟。

图是搜索算法的最常用数据结构,因此需要先储备一些图的概念。

我总结在另一篇博客:
BFS 相对 DFS 的最主要的区别是:BFS 找到的路径一定是最短的,但代价就是空间复杂度比 DFS 大很多

广度优先搜索(Breadth-First-Search)

广度优先的思路比较简单,写 BFS 算法都是用「队列」这种数据结构,每次将一个节点周围的所有节点加入队列。可以通过下面这张图直接理解:

在这里插入图片描述
1.BFS算法思路简述
设置一个数组visited[]存放每个结点是否被访问过
(1)访问第一个顶点,置已访问标志;
(2)取第一个邻接点;
(3)若未被访问过,则对其进行DFS;
(4)取下一个邻接点;
重复(3)、(4)直至所有邻接顶点取完。
BFS是一种分层的搜索过程(典型:树的层次遍历) ,每向前走一步可能访问一批顶点, 不像深度优先搜索那样有往回退的情况。因此, 广度优先搜索不是一个递归的过程。
2.图的代码实现

public class Graph{
//无向图 private int v; //顶点的个数 private LinkedList
adj[]; //邻接表 public Graph(int v){
this.v=v; adj = new LinkedList[v]; for(int i=0;i
(); } } //无向图一条边存两次 public void addEdge(int s, int t){
adj[s].add(t); adj[t].add(s); }}

3.BFS代码实现

搜索一条从 s 到 t 的最短路径:
队列的作用:因为广度优先搜索是逐层访问的,当我们访问到第 k 层的顶点的时候,我们需要把第 k 层的顶点记录下来,稍后才能通过第 k 层的顶点来找第 k+1 层的顶点。所以,我们用这个队列来实现记录的功能。
从顶点 s 开始,广度优先搜索到顶点 t 后,prev 数组中存储的就是搜索的路径。不过这个路径是反向存储的。比如,通过顶点 2 的邻接表访问到顶点 3,那 prev[3]就等于 2。

public void bfs(int s, int t) {
if (s == t) return; //visited 是用来记录已经被访问的顶点,用来避免顶点被重复访问。 boolean[] visited = new boolean[v]; visited[s]=true; //queue 用来存储本身已被访问、但相连的顶点还没有被访问的顶点。 Queue
queue = new LinkedList<>(); queue.add(s); //prev 用来记录搜索路径。 int[] prev = new int[v]; for (int i = 0; i < v; ++i) {
prev[i] = -1; } // while (queue.size() != 0) {
int w = queue.poll(); for (int i = 0; i < adj[w].size(); ++i) {
int q = adj[w].get(i); if (!visited[q]) {
prev[q] = w; if (q == t) {
//搜索到t,直接返回prev数组,注意逆序 print(prev, s, t); return; } visited[q] = true;//顶点 q 被访问,visited[q]置为 true。 queue.add(q); } } }}//为了正向打印出路径,我们需要递归地来打印private void print(int[] prev, int s, int t) {
// 递归打印s->t的路径 if (prev[t] != -1 && t != s) {
print(prev, s, prev[t]); } System.out.print(t + " ");}

本文代码代码部分均来极客时间的《数据结构与算法之美》第31课

转载地址:http://cfrsi.baihongyu.com/

你可能感兴趣的文章
npm和node升级的正确方式
查看>>
laravel事务
查看>>
springcloud 连续请求 500
查看>>
vue复用新增和编辑表单
查看>>
Ubuntu 16.04 apt-get更换为国内阿里云源
查看>>
laravel部署到宝塔步骤
查看>>
小程序获取access_token
查看>>
navicat远程连接mysql数据库
查看>>
tp5令牌数据无效 解决方法
查看>>
自己的网站与UCenter整合(大致流程)
查看>>
laravel 制作通用的curd 后台操作
查看>>
【小红书2017年笔试】求一个数组中平均数最大的子数组
查看>>
【java基础】父类与子类中各成员初始化顺序
查看>>
maven安装并在eclipse中配置
查看>>
三种常见字符编码简介:ASCII、Unicode和UTF-8
查看>>
【剑指offer】链表中倒数第K个节点
查看>>
http 请求中的 referer
查看>>
【携程2018校招】数组中非零元素稳定的放到数组前面,零元素放到数组后面
查看>>
【Mac终端】 root与普通用户切换(root/bash-3.2/sh-3.2/MacBook-Pro区别)
查看>>
【rabbitMQ之二】rabbitMQ之工作队列(消息ACK、消息持久化、公平分派)-go语言
查看>>