数据结构与算法—图论之dfs、bfs(深度优先搜索、宽度优先搜索)
文章目录
- 前言
- 邻接矩阵和邻接表
- 深度优先搜索(dfs)
- 宽度(广度)优先搜索(bfs)
- 总结与比较
前言
在有向图和无向图中,如果节点之间无权值或者权值相等,那么dfs和bfs
时常出现在日常算法中。不仅如此,dfs,bfs不仅仅能够解决图论的问题,在其他问题的搜索上也是最基础(但是策略不同
)的两种经典算法
。
并且五大经典算法的回溯算法
其实也是dfs
的一种。dfs,bfs基础能够解决搜索类问题的大部分情况,只不过搜索随着数据增大而呈非线性的增长,所以两种算法在数据较多的情况是不太适用的。
邻接矩阵和邻接表
邻接矩阵:
邻接矩阵就是用数组(二维)表示图。具体可以看下面例子。当然,这种情况很容易造成空间浪费,所以很多人进行空间优化,甚至是邻接表的方式。
邻接表:
而邻接表则是数组套链表。这样可以比起邻接矩阵节省不少空间,但是如果无向图依然会重复浪费一半空间,就有十字链表,多重链接表等等出现。同时,对于有权图来说,只需对节点加一个属性weight即可!
深度优先搜索(dfs)
概念:
深度优先搜索属于图算法的一种,英文缩写为DFS即Depth First Search.其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次.
简单的说,要完成dfs要有前提条件.就是有联通点
。单个节点dfs就断掉了,他要找打和它联系的节点。dfs入手可能比bfs简单的原因是dfs大部分之间利用递归的走向完成dfs,而很少需要标记
。
我们通常使用邻接表(一维数组套链表a[List])
或者邻接矩阵(二维数组a[][])
储存图的信息。有时为了优化空间会选择十字链表
或者邻接多重表
进行存储节省空间,但是操作往往是很复杂的。并且一般来说图的更大需要设计算法的优化,所以这里例子使用邻接矩阵
完成!
对于dfs的流程来说,大致可以认为是这样:
- 从初始点开始按照一个方向遍历,这个方向到尽头停止后到另一个方向,,,直到所有操作完成退出!
- 深度优先搜索执行过程像是一个栈的操作。
喜新厌旧
。总是处理最新加入的节点,这点递归恰好满足其性质,并且递归代码写起来也更简洁。 - dfs的流程可以参考二叉树的前序遍历,它实质就是一个dfs。
对于上图的dfs。可以用一下代码来表示:
package 图论;
public class dfs {static boolean isVisit[];public static void main(String[] args) {int map[][]=new int[7][7];isVisit=new boolean[7];map[0][1]=map[1][0]=1;map[0][2]=map[2][0]=1;map[0][3]=map[3][0]=1;map[1][4]=map[4][1]=1;map[1][5]=map[5][1]=1;map[2][6]=map[6][2]=1;map[3][6]=map[6][3]=1;isVisit[0]=true;dfs(0,map);//从0开始遍历}private static void dfs(int index,int map[][]) {// TODO Auto-generated method stubSystem.out.println("访问"+(index+1)+" ");for(int i=0;i<map[index].length;i++)//查找联通节点{if(map[index][i]>0&&isVisit[i]==false){isVisit[i]=true;dfs(i,map);}}System.out.println((index+1)+"访问结束 ");}
}
大致顺序访问为
宽度(广度)优先搜索(bfs)
概念:
BFS,其英文全称是Breadth First Search。 BFS并不使用经验法则算法。从算法的观点,所有因为展开节点而得到的子节点都会被加进一个先进先出的队列中。一般的实验里,其邻居节点尚未被检验过的节点会被放置在一个被称为 open 的容器中(例如队列或是链表),而被检验过的节点则被放置在被称为 closed 的容器中。(open-closed表)
简单来说,bfs就是先进先出的队列遍历,然而这样在分布的情况就是按层遍历,可以参考二叉树遍历的层序遍历!
如果从路径上走来看,dfs就是一条跑的很快的疯狗,到处乱咬。没路了就转头,再没路了再跑回来去其他地方,而bfs就像是一团毒气,慢慢延申!
就拿上述的图来说,我们使用邻接表来实现遍历。
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;public class bfs {public static void main(String[] args) {List<Integer> map[]=new ArrayList[7];boolean isVisit[]=new boolean[7];for(int i=0;i<map.length;i++)//初始化{map[i]=new ArrayList<Integer>();}map[0].add(1);map[0].add(2);map[0].add(3);map[1].add(0);map[1].add(4);map[1].add(5);map[2].add(0);map[2].add(6);map[3].add(0);map[3].add(6);map[4].add(1);map[5].add(1);map[6].add(2);map[6].add(3);Queue<Integer>q1=new ArrayDeque<Integer>();q1.add(0);isVisit[0]=true;while (!q1.isEmpty()) {int va=q1.poll();System.out.println("访问"+(va+1));for(int i=0;i<map[va].size();i++){int index=map[va].get(i);if(!isVisit[index]){q1.add(index);isVisit[index]=true;}}}}
}
总结与比较
上面说到dfs和bfs往往是在寻路上的两个极端的表现!当然在不同场景使用可能也有些不同。
- dfs可以运用在查找和爬虫中,如果爬虫的话那么更多是优先找到不同链接,可用于统计等。而在查找中比如迷宫类可以利用dfs判断是否存在路径,出路等等。
- bfs也可以运用在算法和爬虫之中。而bfs优先处理自己周围的资源。所以在爬虫可以用于遍历网站,搜寻整个网站的价值信息等等,笔者以前用爬虫+bfs实现过下载网站的模板(17素材的网页模板)。而在算法中,在迷宫或者无权图中,bfs可以找到最短路径。
在上面可以看得出在邻接矩阵实现储存上浪费很多空间,但有些情况使用二维数组很合适——迷宫类问题。我们在面试学习,会经常遇到迷宫类需要bfs找最短路径,或者dfs查询是否存在。或者双bfs又或者dfs+bfs等等解决具体问题。
最后,希望大家能关注我(bigsai),我们一起学习数据结构与算法!感觉还行,可以动动小手,点个赞!
数据结构与算法—图论之dfs、bfs(深度优先搜索、宽度优先搜索)相关推荐
- 广度优先搜索 - 宽度优先搜索 - 横向优先搜索 (breadth-first search,BFS)
广度优先搜索 - 宽度优先搜索 - 横向优先搜索 (breadth-first search,BFS) 1. 广度优先搜索 - 宽度优先搜索 - 横向优先搜索 (breadth-first searc ...
- 生成图-深度优先搜索/宽度优先搜索
问题提出: 考虑如下图所示的简单图所表示的缅因州的道路系统.在冬天里保持道路通路通畅的唯一方式就是经常扫雪.高速公路部分希望只扫尽可能少的道路上的雪,而确保总是存在连接任何两个乡镇的干净道路.如何才能 ...
- 迷宫问题 深度优先搜索 广度优先搜索 宽度优先搜索【python】
文章目录 一.实验内容 二.深度优先搜索和广度优先搜索总结 1.深度优先搜索算法 2.广度优先搜索算法 三.实验代码和用于测试的迷宫 1.实验代码 2.测试迷宫 2.1 maze1.txt 2.2 m ...
- 深度优先搜索与宽度优先搜索
深度优先搜索 简称:DFS 基本思路 深度优先遍历图的方法是,从图中某顶点v出发: (1)访问顶点v: (2)依次从v的未被访问的邻接点出发,对图进行深度优先遍历:直至图中和v有路径相通的顶点都被访问 ...
- 数据结构与算法--图论-深度优先搜索及其应用
深度优先搜索 深度优先搜索(depth-first search) 是对先序遍历(preorder traversal)的推广,我们从某个顶点v开始处理v,然后递归的遍历所有与v邻接顶点.如果这个过程 ...
- 算法笔记01——深度优先搜索(DFS)/宽度优先搜索(BFS)
深度优先搜索(DFS) 从某个状态开始,不断地转移状态直到无法转移,然后回退到前一步的状态,继续转移到其他状态,如此不断重复,直至找到最终的解.深度优先搜索从最开始的状态出发,遍历所有可以到达的状态. ...
- 数据结构与算法--图论最短路径算法应用-词阶求解
最短路径案例 词梯应用,在一个词梯中,每个单词均由前一个单词改变一个字母而得到.例如,我们通过一系列单字母替换而得到zero转换为five,如下:five:zero,hero,here,hire,fi ...
- SDUT 2142 数据结构实验之图论二:基于邻接表的广度优先搜索遍历
数据结构实验之图论二:基于邻接表的广度优先搜索遍历 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Problem Descript ...
- ACM算法笔记(十)深度优先搜索与宽度优先搜索
深度优先搜索 事实上,深度优先搜索属于图算法的一种,英文缩写为DFS即Depth First Search.其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次. 下面 ...
最新文章
- 51Nod - 1035 最长的循环节
- SpringBoot应用之消息队列rabbitmq
- python获取已打开网页的html,【已解决】Python的BeautifulSoup去实现提取带tag的HTML网页主体内容...
- java建站系统开发教程系列之设计表结构
- java文件读取的几个操作-2
- android 开源病毒库,ClamAV+ClamTK,开源杀毒软件
- 安卓图片自适应的解决办法
- Android物联网应用程序开发(智慧城市)—— 购物信息的存储界面开发
- 淘系双十一全链路压测流程概览
- 一分钟学习静态网页制作
- 520送男朋友什么礼物最好、送男友礼物清单
- Java SE 6.0实现高质量桌面集成开发
- 打字游戏之主界面实现
- Kali获取手机照片
- mysql checking_高并发下MySQL出现checking permissions
- 拉格朗日乘法解决约束条件下的最优问题
- google 访问统计
- 倍加福耦合器KFD2-BR-1.PA.1500
- html加js动态效果图,JS动态图片的实现方法完整示例
- window下SVN使用教程