BFS——广度优先搜索的简单易懂入门心得

本文介绍了BFS(广度优先搜索)的基本概念,使用C++实现,并对比了与DFS的区别。通过队列实现BFS,强调其在寻找最短路径问题上的优势,举例展示了BFS在迷宫问题中的应用。

BFS(广度优先搜索)。

本文应用的语言为C++。

在了解之前,稍微简单介绍一下C++库里STL里的 queue(队列),一个数据“先进先出”的数据结构。

首先调用库queue
定义:queue<数据类型>队列名称;
.push( 数据 );将数据加入队列
.pop();将队首数据弹出队列
.front();取出队列首的数据,但不删除。

为什么需要用到队列呢?
假设我们建立了一棵树,想要搜索其中的某个节点。

如果我们学习了DFS我们知道,DFS是从根节点开始,选择一条树枝,完全搜寻一棵树枝上的所有节点后找不到后,才会递归回去搜寻另一条树枝上面的节点。
有一个特点,就是我们正在处理的那个节点一定来自同枝干上的父节点。
即,现在处理的节点是刚才处理的节点的分支。刚处理完的节点的连线是“竖直”的。

而BFS不同,它是搜寻到一个树枝的节点后,再处理其他树枝同样高度的节点后,才走原树枝到下一个高度的节点。刚处理完的节点连线是“水平”的。

我们来个例子,建立一棵树:

树根就是 e ,假设我们要找 f 吧。方向是从上到下,从左到右
我们来用动态图来描述DFS和BFS不同的行为。
在这里插入图片描述
e->b->a
e->b->d->c
是不是像一条“竖直线”?,不到最底不回头。
在这里插入图片描述
 b->g
 a->d->f
是不是像一条“水平”线?,走完一层再走下一层。

然后回到最初的问题,为什么要用queue?

因为每次从队列里拿出来的要处理节点,并不是刚才就处理完的节点的分支,而是在此之前就已经处理完的节点的分支(“先进先出”)。就如图中,我们处理完g,把它的分支f放到队伍最后面,下一个要处理的是在g之前就已经处理完的,b的分枝a,然后到d,最后才到f。

如果我们用栈(stack先进后出)的话,要处理的节点是刚才节点的分支。就如图中,我们处理完b,按照由左往右顺序,先处理掉它的左分支a,而不是处理g。

然后因为b和f都有相同的分支d,所以在放节点进入队列的时候要先创立一个数组存放记录已进过队列里的节点,已进过队列里的节点不能重复进入,以防一个节点重复“开花”造成系统崩溃。

/注意:其实这里的树并不是严格的“树”,应该是数据类型里的图表,文中称树是为了方便描述。现实中有树长成圈那样的吗/dog,有当我没说XD/

全代码:

#include<iostream>
#include<cstdlib>
#include<queue>
using namespace std;
struct tree{
   
   
char saveChar;
int step;
struct tree*L;
struct tree*R;
};
struct tree*c;
struct tree*f;
struct list {
   
   
struct tree*head;
};
void putin(struct tree*p,struct tree*prep){
   
   
if(p->saveChar<prep->saveChar){
   
   
    if(prep->L!=NULL){
   
   putin(p,prep->L);}
    else{
   
   prep->L=p;return;}
}
if(p->saveChar>prep->saveChar){
   
   
    if(prep->R!=NULL){
   
   putin(p,prep->R);}
    else{
   
   prep->R=p;return;}
}
}
void ShowAndRecord(struct tree*p){
   
   
    if(p!=NULL){
   
   
    if(p->saveChar=='d'){
   
   c=p;}
    if(p->saveChar=='g'){
   
   f=p;}
    //cout<<p->saveChar<<endl;
    }
if(p->L!=NULL){
   
   
    ShowAndRecord(p->L);
}
if(p->R!=NULL){
   
   
    ShowAndRecord(p->R);
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值