BFS与DFS的不同之处在于搜索的顺序:BFS总是先搜索距离初始状态近的状态;而DFS是从某个状态开始,不断地转移状态直至无法转移,然后退到前一步的状态,继续转移其他状态,如此不断重复,直至找到最终的解。
BFS按照距离开始状态由近及远的顺序进行搜索,因此可以很容易地用来求最短路径、最少操作之类问题的答案。如下面的走迷宫问题。
【问题描述】给定一个大小为M×N的迷宫。迷宫由通道和墙壁组成,每一步可以向邻接的上下左右四个的通道移动。请求出从起点到终点所需的最小步数。请注意,本题假定从起点一定可以移动到终点。
【限制条件】M,N≤100
【输入样例】第一行分别是迷宫的行数和列数;下面是一个M×N的矩阵表示迷宫(其中‘#’、‘.’、‘S’、‘G’分别表示墙壁、通道、起点和终点)。
10 10
#S######.#
......#..#
.#.##.##.#
.#........
##.##.####
....#....#
.#######.#
....#.....
.####.###.
....#...G#
【输出】
22
Python实现:
m,n=map(int,input().split())
a=["0" for j in range(m)] # 迷宫矩阵
d=[[-1 for j in range(n)] for i in range(m)] # 到各个位置的最短距离
sx,sy,gx,gy=-1,-1,-1,-1 # 起点和终点的横纵坐标
# 4个方向移动的向量
dx=[1,0,-1,0]
dy=[0,1,0,-1]
# 输入迷宫
for i in range(m):
a[i]=input()
# # 输出迷宫
# print(a)
# 找出起点和终点的坐标
for i in range(m):
for j in range(n):
if a[i][j]=="S": # 起点
sx=i
sy=j
if a[i][j]=="G": # 终点
gx=i
gy=j
# 点类
class P:
x=-1
y=-1
def __init__(self,x,y):
self.x=x
self.y=y
def bfs():
l=[]
l.append(P(sx,sy))
d[sx][sy]=0
# 不断循环直至队列为空
while(len(l)>0):
p=l[0]
del l[0]
# 到达终点
if p.x==gx and p.y==gy:
break
# 四个方向的循环
for i in range(4):
nx=p.x+dx[i]
ny=p.y+dy[i]
# 判断是否可以移动以及是否已经访问过
if 0 <= nx < m and 0 <= ny < n and a[nx][ny]!= "#":
l.append(P(nx,ny))
d[nx][ny]=d[p.x][p.y]+1
return d[gx][gy]
print(bfs())
小技巧:因为要向4个不同方向移动,用dx[4]和dy[4]两个数组来表示四个方向向量。这样通过一个循环就可以实现四方向移动的遍历。
关于DFS的应用问题可以看这一篇Lake Counting(POJ No.2386)。