简谈BFS
BFS的最好理解就是“层次遍历”,他是一层层往下走的。时间复杂度同DFS。

重点在于使用队列来缓存要遍历的结点。
给出核心代码(c++):使用STL中的queue,vex[v][vi] is adjacent matrix
queue<int> que;
que.push(v0); //v0是起始点
while(!que.empty()){
int v = que.front(); //取队头
que.pop(); //出队
for(int vi=;vi<n;vi++){
if(vex[v][vi]){
que.push(vi); //vi入队
}
}
}
BFS可以推广到三维数组,用于计算由像素块组成的三维不规则物体体积、三维物体的连通情况。之前在PAT题目中遇到过一次,在此特别记录一下这样题目的处理方法。
这种题目是二维BFS走迷宫过程的一种扩展。先说一下三维数组的表示以及初始化:
pixel vex[][][];
for(int z=;z<l;z++){
for(int x=;x<n;x++){
for(int y=;y<m;y++){
vex[z][x][y].x = x;
vex[z][x][y].y = y;
vex[z][x][y].z = z;
vex[z][x][y].state = ;
}
}
}
假设v[z][x][y]=1说明这点被像素所填充,这样上面的代码就构造了n*m*l完全被填充的立方体。
再来假设搜索位上下左右前后,那么BFS的方向数组又该如何设计?
int x[] = {,,-,,,};
int y[] = {,,,-,,};
int z[] = {,,,,,-};
那么接下来BFS的核心很好处理了
检验函数,可以很好的避免堆栈溢出~~
bool check(int z,int x,int y){
return tz>= && tz<l && tx>= && tx<n && ty>= && ty<m;
}
que<pixel> vex;
while(!que.empty()){
pixel v = que.front();
que.pop();
for(int i=;i<;i++){
int tz = v.z+z[i]; //求下个点
int tx = v.x+x[i];
int ty = v.y+y[i];
check(tz,tx,ty) continue;
if( vex[tz][tx][ty] ){ //可以到达
que.push(vex[tz][tx][ty]);
}
}
}
以上就是三维物体体积的BFS求解方式。之后再说一个个人观点,二维平面求不规则面积的问题似乎也可以用这种方式解决。
BFS在做层次遍历的时候我们要怎样记录各点所属的层呢?
while(!que.empty()){
vi = que.front();
if(layer[vi] > maxlayer){
maxlayer = layer[vi]; //BFS tree的深度
index = ; //初始化为极大
}
if(vi != v0){
index = min(index,vi); //最深那层中的编号最小的点
}
for(int i=;i<=n;i++){
if(!visit[i] && v[vi][i] != ){
visit[i] = true;
layer[i] = layer[vi]+; //进入了下一层,记录下i点所在的层数
que.push(i);
}
}
que.pop();
}
以上代码是PAT中“喊山”一题的核心代码,很好的诠释了了BFS过程中层次的维护方法。
将来遇到了新问题还会作补充。。。
简谈BFS的更多相关文章
- .NET简谈接口
自从面向对象开发方式的出现,抽象的概念就开始日新月异的发展,面向对象编程.面向接口编程.面向组件编程等等:这一系列的概念都是软件工程所追求的思想范畴,高类聚低耦合. 今天我要简谈的是面向对象里面非常重 ...
- .NET简谈构件系统开发模式
转自[王清培] http://www.cnblogs.com/wangiqngpei557/archive/2011/06/14/2080416.html 在本人的“.NET简谈插件系统开发模式”一文 ...
- .NET简谈——跨进高级编程门槛的必经之路
我们继续C#基础知识的学习,这篇文章对前面基础知识学习的朋友有着举足轻重的作用:为了延续基础知识学习的热情,我编写了这篇特殊的文章. 本篇文章的中心是想借“.NET简谈反射(动态调用)”一文继续发挥下 ...
- 简谈Java语言的继承
Java语言的继承 这里简谈Java语言的三大特性之二——继承. Java语言的三大特性是循序渐进的.是有顺序性的,应该按照封装-->继承-->多态这样的顺序依次学习 继承的定义 百度百科 ...
- 简谈Java语言的封装
简谈Java语言的封装 封装的定义 封装将复杂模块或系统的逻辑实现细节隐藏,让使用者只需要关心这个模块或系统怎么使用,而不用关心这个模块或系统是怎么实现的. 在面向对象的的编程中,我们一般通过接口来描 ...
- MPI简谈
MPI简谈 MPI是分布式内存系统,区别于OpenMP和Pthreads的共享内存系统.MPI是一种基于消息传递的并行编程技术,是如今最为广泛的并行程序开发方法. MPI前世今生 MPI(Messag ...
- ASP.NET MVC 网站开发总结(六)——简谈Json的序列化与反序列化
首先,先简单的谈一下什么是序列化与反序列化,序列化 (Serialization)将对象的状态信息转换为可以存储或传输的形式的过程.在序列化期间,对象将其当前状态写入到临时或持久性存储区.以后,可以通 ...
- 简谈HTML5与APP技术应用
HTML5到底能给企业带来些什么? HTML5是近年来互联网行业的热门词汇,火的很.微软IE产品总经理发文: 未来的网络属于HTML5.乔布斯生前也在公开信<Flash之我见>中预言:像H ...
- 简谈WP,IOS,Android智能手机OS
什么是智能手机? 相信到现在这个已经是傻瓜到不能再傻瓜的问题了 智能手机都不懂? 那你活着还有什么意思= = 但是为了谈论今天的三大主角:wp,ios,android 不得不回答一下这个笨笨的问题 如 ...
随机推荐
- RAC环境上搭建DG
首先RAC要确实是开归档的状态archive log list;如果是非归档状态,需要执行下面几步srvctl stop database -d +数据库实例名 关闭数据库--节点1(要做DG主库的) ...
- 怎么训练出一个NB的Prophet模型
上篇<神器の争>主要是介绍Prophet的特点以及prophet入门的一些注意事项,但离真正的实际运用还有段距离.本篇主要讲解实际运用中Prophet调参的主要步骤以及一些本人实际经验. ...
- 题解 洛谷 P5465 【[PKUSC2018]星际穿越】
首先考虑题目的性质,发现点向区间连的边为双向边,所以也就可以从一个点向右跳到区间包含该点的点,如图所示: 但事实上向后跳其实是不优的,可以有更好的方法来节省花费: 因此我们发现一个点跳到其前一个区间的 ...
- SpringBoot 整合Mybatis + PageHelper 实现分页
前言: 现在公司大多数都实现了前后端分离,前端使用Vue.React.AngularJS 等框架,不用完全依赖后端.但是如果对于比较小型的项目,没必要前后端分离,而SpringBoot也基本抛弃了Js ...
- .Net Core缓存组件(MemoryCache)【缓存篇(二)】
一.前言 .Net Core缓存源码 1.上篇.NET Core ResponseCache[缓存篇(一)]中我们提到了使用客户端缓存.和服务端缓存.本文我们介绍MemoryCache缓存组件,说到服 ...
- 3分钟看懂Python后端必须知道的Django的信号机制!
概念 django自带一套信号机制来帮助我们在框架的不同位置之间传递信息.也就是说,当某一事件发生时,信号系统可以允许一个或多个发送者(senders)将通知或信号(signals)发送给一组接受者( ...
- JS 原生ajax写法
<script> //step1.创建XMLHTTPRequest对象,对于低版本的IE,需要换一个ActiveXObject对象 var xhr; if (window.XMLHttpR ...
- PHP jewishtojd() 函数
------------恢复内容开始------------ 实例 把犹太历法的日期转换为儒略日计数: <?php$jd=jewishtojd(6,20,2007);echo $jd;?> ...
- PHP set_exception_handler() 函数
定义和用法 set_exception_handler() 函数设置用户自定义的异常处理函数. 该函数用于创建运行期间的用户自己的异常处理方法. 该函数返回旧的异常处理程序,如果失败则返回 NULL. ...
- 实战:一键生成前后端代码,Mybatis-Plus代码生成器让我舒服了
实战:一键生成前后端代码,Mybatis-Plus代码生成器让我舒服了 前言 在日常的软件开发中,程序员往往需要花费大量的时间写CRUD,不仅枯燥效率低,而且每个人的代码风格不统一.MyBatis-P ...