理解广度优先搜索

本文详细介绍了广度优先搜索(BFS)的基本概念、队列的应用,以及三个典型实例:八数码问题、单词阶梯(word ladder)问题和Word Ladder II问题。在BFS过程中,需要考虑节点判重和路径记录,同时通过实例展示了如何利用BFS解决实际问题,如寻找最短路径和解决约束条件下的变换序列。
摘要由CSDN通过智能技术生成

1.   定义

BFS是Breath First Search的缩写,是广度优先搜索的意思,是图的遍历方式的一种。

由于BFS是从起点一层一层的进行搜索的,所以凡是需要求最短路径的问题,都可以尝试看BFS能否解决,比如Dijkstra的单源最短路径算法使用了BFS的思想。另外,在执行广度优先搜索的过程中将构造出一棵树,这也是Prim的最小生成树算法思想。在做BFS的时候,有两点需要特别注意:

1.      为了防止搜索进入无限循环,节点需要判重,也就是已经访问过的节点不要再访问了,所以需要记录一个节点是不是已经访问过了。

2.      另外BFS有可能会要求记录路径,这时候需要记录一个节点的前驱节点。这些信息可以保存在节点数据结构里,也可以存在map里,比如C++的unordered_map。如果只记录一个前驱节点,那我们只能记录一个路径。但是如果记录所有前驱,则我们可以记录所有路径。

算法导论上的伪代码如下,很经典

1  for each vertex u ∈ V [G] - {s}

 2      do color[u] ← WHITE

 3         d[u] ←∞

 4         π[u] ← NIL

 6  d[s] ← 0

 7  π[s] ← NIL

 8  Q ← Ø

 9 ENQUEUE(Q, s)

10  while Q ≠ Ø

11      do u ← DEQUEUE(Q)

12         for each v ∈ Adj[u]

13             do if color[v] = WHITE

14                   then color[v] ← GRAY

15                        d[v] ← d[u] + 1

16                        π[v] ← u

17                        ENQUEUE(Q, v)

18         color[u] ← BLACK

2.   队列

C++中的queue,这是一种FIFO队列,还有一种Priorityqueue,这里就不讨论了。如果不使用STL,那么队列一般用数组或链表来实现。

(constructor)

Construct queue (public member function )

empty

Test whether container is empty (public member function )

size

Return size (public member function )

front

Access next element (public member function )

back

Access last element (public member function )

push

Insert element (public member function )

emplace

Construct and insert element (public member function )

pop

Remove next element (public member function )

swap

Swap contents (public member function )

 

3.   例一:八数码问题

八数码问题也称为九宫问题。在3×3的棋盘,摆有八个棋子,每个棋子上标有1至8的某一数字,不同棋子上标的数字不相同。棋盘上还有一个空格,与空格相邻的棋子可以移到空格中。要求解决的问题是:给出一个初始状态和一个目标状态,找出一种从初始转变成目标状态的移动棋子步数最少的移动步骤。


分析:这道题关键在于抽象出图的节点和路径,看下图:每个状态都是图的一个节点,而从一个状态如果能一次转换到另一个状态的话,我们认为这两个节点之间有边。这样,就抽象出一个图。这样,对这个图做BFS,就能找到到目标状态的最短路径。

 

uno
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值