广度优先搜索BFS(Breadth First Search)也称为宽度优先搜索,它是一种先生成的结点先扩展的策略。

在广度优先搜索算法中,解答树上结点的扩展是按它们在树中的层次进行的。首先生成第一层结点,同时检查目标结点是否在所生成的结点中,如果不在,则将所有的第一层结点逐一扩展,得到第二层结点,并检查第二层结点是否包含目标结点,……,对层次为n+1的任一结点进行扩展之前,必须先考虑层次完层次为n的结点的每种可能的状态。因此,对于同一层结点来说,求解问题的价值是相同的,可以按任意顺序来扩展它们。通常采用的原则是先生成的结点先扩展。

为了便于进行搜索,要设置一个表存储所有的结点。由于在广度优先搜索算法中,要满足先生成的结点先扩展的原则,所以存储结点的表一般采用队列这种数据结构。

在编写程序时,可用数组q模拟队列。front和rear分别表示队头指针和队尾指针,初始时front=rear=0。

元素x入队操作为 q[rear++]=x;

元素x出队操作为 x =q[front++];

广度优先搜索算法的搜索步骤一般是:

(1)从队列头取出一个结点,检查它按照扩展规则是否能够扩展,如果能则产生一个新结点。

(2)检查新生成的结点,看它是否已在队列中存在,如果新结点已经在队列中出现过,就放弃这个结点,然后回到第(1)步。否则,如果新结点未曾在队列中出现过,则将它加入到队列尾。

(3)检查新结点是否目标结点。如果新结点是目标结点,则搜索成功,程序结束;若新结点不是目标结点,则回到第(1)步,再从队列头取出结点进行扩展。

最终可能产生两种结果:找到目标结点,或扩展完所有结点而没有找到目标结点。

如果目标结点存在于解答树的有限层上,广度优先搜索算法一定能保证找到一条通向它的最佳路径,因此广度优先搜索算法特别适用于只需求出最优解的问题。当问题需要给出解的路径,则要保存每个结点的来源,也就是它是从哪一个节点扩展来的。

对于广度优先搜索算法来说,问题不同则状态结点的结构和结点扩展规则是不同的,但搜索的策略是相同的。广度优先搜索算法的框架一般如下:

void BFS()

{

队列初始化;

初始结点入队;

while (队列非空)

{

队头元素出队,赋给current;

while (current 还可以扩展)

{

由结点current扩展出新结点new;

if (new 重复于已有的结点状态) continue;

new结点入队;

if (new结点是目标状态)

{

置flag= true; break;

}

}

}

}

对于不同的问题,用广度优先搜索法的算法基本上都是一样的。但表示问题状态的结点数据结构、新结点是否为目标结点和是否为重复结点的判断等方面则有所不同。对具体的问题需要进行具体分析,这些函数要根据具体问题进行编写。

【例1】黑色方块

有一个宽为W、高为H的矩形平面,用黑色和红色两种颜色的方砖铺满。一个小朋友站在一块黑色方块上开始移动,规定移动方向有上、下、左、右四种,且只能在黑色方块上移动(即不能移到红色方块上)。编写一个程序,计算小朋友从起点出发可到达的所有黑色方砖的块数(包括起点)。

例如,如图1所示的矩形平面中,“#”表示红色砖块,“.”表示黑色砖块,“@”表示小朋友的起点,则小朋友能走到的黑色方砖有28块。

(1)编程思路

采用广度优先搜索法解决这个问题。

用数组q模拟队列操作,front为队头指针,rear为队尾指针,初始时front=rear=0。

入队操作为 q[rear++]=cur;

出队操作为 cur=q[front++]。

程序中定义方砖的位置坐标(x,y)为Node类型,定义数组int

visit[N][N]标记某方砖是否已走过,visit[i][j]=0表示坐标(i,j)处的方砖未走过,visit[i][j]=1表示坐标(i,j)处的方砖已走过。初始时visit数组的所有元素值均为0。

具体算法步骤为:

① 将出发点(startx,starty)入队列q,且置visit[startx][starty]=1,表示该处的方砖已被处理,以后不再重复搜索。

② 将队列q的队头元素出栈,得到一个当前方砖cur,黑色方砖计数(sum++),沿其上、下、左、右四个方向上搜索未走过的黑色方砖,将找到的黑色方砖的坐标入队列q。

③ 重复执行②,直至队列q为空,则求出了所有能走过的黑色方砖数。

(2)源程序

#include <iostream>

using namespace std;

#define N 21

struct Node

{

int x;

int y;

};

int dx[]={-,,,};

int dy[]={,,-,};

char map[N][N];

int visit[N][N];

int bfs(int startx, int starty,int w,int h)

{

Node q[N*N],cur,next; // q为队列

int front,rear; // front为队头指针,rear为队尾指针

int i,x,y,sum;

front=rear=; // 队列q初始化

sum=;

cur.x=startx; cur.y=starty;

visit[startx][starty]=;

q[rear++]=cur; // 初始结点入队

while(rear!=front) // 队列不为空

{

cur=q[front++]; // 队头元素出队

sum++; // 方砖计数

for (i=;i<;i++)

{

x=cur.x+dx[i]; y=cur.y+dy[i];

if(x >= &&

x<h && y>= && y<w && map[x][y]!='#'

&& visit[x][y]==)

{

visit[x][y] = ;

next.x=x; next.y=y; // 由cur扩展出新结点next

q[rear++]=next; // next结点入队

}

}

}

return sum;

}

int main()

{

int i,j,pos_x,pos_y,w,h,sum;

while()

{

cin>>w>>h;

if (w== && h==) break;

for(i=;i<h;i++)

{

for(j=;j<w;j++)

{

cin>>map[i][j];

if (map[i][j]=='@')

{

pos_x = i;
pos_y = j;
}
visit[i][j] = 0;
}
}
sum=bfs(pos_x, pos_y,w,h);
cout<<sum<<endl;
}
return ;
}

c++之广度优先搜索的更多相关文章

  1. 图的广度优先搜索(BFS)

    把以前写过的图的广度优先搜索分享给大家(C语言版) #include<stdio.h> #include<stdlib.h> #define MAX_VERTEX_NUM 20 ...

  2. 广度优先搜索(BFS)

    定义 维基百科:https://en.wikipedia.org/wiki/Breadth-first_search 给定图G=(V,E)和一个可识别的源结点s,广度优先搜索对图G中的边进行系统性的探 ...

  3. 总结A*,Dijkstra,广度优先搜索,深度优先搜索的复杂度比较

    广度优先搜索(BFS) 1.将头结点放入队列Q中 2.while Q!=空 u出队 遍历u的邻接表中的每个节点v 将v插入队列中 当使用无向图的邻接表时,复杂度为O(V^2) 当使用有向图的邻接表时, ...

  4. ACM题目————图的广度优先搜索

    题目描述 图的广度优先搜索类似于树的按层次遍历,即从某个结点开始,先访问该结点,然后访问该结点的所有邻接点,再依次访问各邻接 点的邻接点.如此进行下去,直到所有的结点都访问为止.在该题中,假定所有的结 ...

  5. SDUT 2141 【TEST】数据结构实验图论一:基于邻接矩阵的广度优先搜索遍历

    数据结构实验图论一:基于邻接矩阵的广度优先搜索遍历 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Discuss Problem ...

  6. HDU 1312 Red and Black DFS(深度优先搜索) 和 BFS(广度优先搜索)

    Red and Black Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total ...

  7. HDU 1241 Oil Deposits DFS(深度优先搜索) 和 BFS(广度优先搜索)

    Oil Deposits Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total ...

  8. HDU 1242 Rescue (BFS(广度优先搜索))

    Rescue Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submis ...

  9. SDUT2142数据结构实验之图论二:基于邻接表的广度优先搜索遍历

    http://acm.sdut.edu.cn/sdutoj/showproblem.php?pid=2142&cid=1186 题目描述 给定一个无向连通图,顶点编号从0到n-1,用广度优先搜 ...

  10. 广度优先搜索BFS

    广度优先搜索可以形成一个广度优先搜索树 算法时间为O(V+E),两重循环 输入:图g,起点start(int) 需要的数据结构:队列Q.color数组(存放每个顶点的颜色) 算法过程: 1. 预处理: ...

随机推荐

  1. jpa随手笔记

    jpa注解1.设置Pojo为实体@Entity //标识这个pojo是一个jpa实体 2.设置表名@Table(name = "users") //指定表名为users 3.设置主 ...

  2. 读取文件夹内容解析为Tree结构

    package com.mine.io; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import ...

  3. Ubuntu14.04 安装VMware tools

    Ubuntu14.04 安装VMware tools 方法一: 1. 在VMware 11(个人的测试环境为vm 11版本)下安装Ubuntu镜像:ubuntu-14.04.1-desktop-amd ...

  4. 云原生时代高性能Java框架—Quarkus(一)

    --- Quarkus&GraalVM介绍.创建并启动第一个项目 Quarkus系列博文 Quarkus&GraalVM介绍.创建并启动第一个项目 构建Quarkus本地镜像.容器化部 ...

  5. JavaScript数组在指定某个元素前或后添加元素

    //原数组 var s = [['g','g'],['h','h'],['i','i']]; //要添加的元素 var s1 = ['a','b','c']; //要添加的元素 var s2 = [' ...

  6. 【转载】基于dom的一些前端漏洞

    最直接的xss --dom xss function trackSearch(query) { document.write('<img src="/resources/images/ ...

  7. O、Θ、Ω、o、ω,别再傻傻分不清了!

    前言 本篇文章收录于专辑:http://dwz.win/HjK,点击解锁更多数据结构与算法的知识. 你好,我是彤哥,一个每天爬二十六层楼还不忘读源码的硬核男人. 前面几节,我们一起学习了算法的复杂度如 ...

  8. SpringBoot-使用lombok插件运行报错

    SpringBoot-使用lombok插件运行报错 标签(空格分隔): java,SpringBoot 1.报错信息 2.解决方案 1.IDEA编辑器安装lombok插件 2.编译注解配置-Enabl ...

  9. Fortify Audit Workbench 笔记 Unreleased Resource: Database( 未释放资源:数据库)

    Unreleased Resource: Database 未释放资源:数据库 Abstract 程序可能无法成功释放某一项系统资源. Explanation 程序可能无法成功释放某一项系统资源. 资 ...

  10. 读取 csv , xlsx 表格并添加总分列

    import pandas as pd import numpy as np data = pd.read_excel('学生成绩表.csv',columns = ['学号','姓名','高数','英 ...