从今天起,我们开始讲广度优先搜索。
1.什么是搜索
C++里的搜索可不是你出门时找不到,然后满屋子搜索。简单来说,广度优先搜索就是走迷宫,你要从起点走到终点,并且要是最短的路径。
2.例题
举个栗子 :
【题目描述】
小a被困在了一个迷宫里,他需要马上回到家。他的位置在(1,1)。迷宫是一个n×m的矩形。迷宫里有一些怪兽,有怪兽的点标为#号,没怪兽的地方标为&号,小a的家标为@,他每次可以向上下左右四个方向走,但不能走入怪兽的格子里。问你他最少要走多少次才能到家?如果到不了,请输出-1
。
【输入样例1】
5 5
&&&#&
#&&##
&&###
&###&
&@###
【输出样例1】
7
【输入样例2】
2 3
&#&
#&@
【输出样例2】
-1
3.队列是什么
看了刚才这道题,是不是有些无从下手🤣???这其实就是一道标准的BFS模板题哦!不用着急,我们慢慢来看。要想学会广度优先搜索,要先学会一个数据结构,那就是——队列。
先来看一些杂七杂八的概念:
1、队列(Queue)的特点:
(1)队列中的数据元素遵循“先进先出”(First In First Out)的原则,简称FIFO结构;
(2)在队尾添加元素,在队头删除元素。
2、队列的相关概念:
(1)队头与队尾: 允许元素插入的一端称为队尾,允许元素删除的一端称为队头;
(2)入队:队列的插入操作;
(3)出队:队列的删除操作。
3、队列的操作:
(1)入队: 通常命名为q.push()
(2)出队: 通常命名为q.pop()
(3)求队列中元素个数q.size()
(4)判断队列是否为空q.empty()
(5)获取队首元素q.front()
4、队列的分类:
(1)基于数组的循环队列(循环队列)
(2)基于链表的队列(链队列)
——————————————————
说了这么多,其实你可以把队列当成一个做核酸的队伍,如下图。
因为小a是第一个来的,所以他先做完核酸。接下来做核酸的顺序是先小b再小c。所以队列是个先进先出的数据结构。
4.为什么要用队列呢
知道队列是什么了吧!现在问题来了:为什么要用队列呢?它在搜索中有什么特别的“法力”呢?要知道这个问题,我们画一个迷宫就好了。
上图是一个参照输入样例1画出来的迷宫,起点在(1,1)的位置。按照搜索顺序依次往四个方向走。
往上走出迷宫。
往下遇到怪兽。
往左走出迷宫。
往右走至一号点。
上下左右都走了一遍,小a发现只能往右走到一号点,所以我们就让一号点第一天来做核酸(进队列),做完核酸后,一号点说:“我做完了,我要出队列,但我要让二号和三号点第二天来做核酸。”这是因为小a走到一号点后,发现只能走往二号点和三号点。而二号点和三号点又不约而同的叫来的四号点,四号点又叫来了五号点……直到所有点都做完核酸(除走不到的点以外),及队列为空。
————————————————
通过刚才这个做核酸的过程,你理解了队列在搜索中是怎么使用的吗?走向四周这个过程我会在下一讲给你详细讲解哦!
好了,今天对广度优先搜索的讲解就先到这里,下一章我们不见不散哦!
最后
原创不易,如果对您有帮助,请点个赞再走呀(づ ̄3 ̄)づ╭❤