1.思路:可以敏锐的察觉,迷宫这个问题可以采用递归的思路
- 查询当前位置是否是出口
- 是:返回True
- 否:继续查找本位置的四个邻边位置
- 用for 循环 每一个邻边位置都要找
- if 一旦有找到,立即停止搜寻。返回True
- 在程序最后还没有返回True
- 只好返回 Flase
从这个递归过程,让我再一次深刻认识到递归的实现过程:
- 从最简单的情况开始,返回结果
- 如果没有到达,最简单的情况,找到本次情况的下一个情况(有时,不止下一个情况,可能是很多情况并列,比如本题:这个时候就要用if 语句(排除已经访问过的),或者for 循环来一个一个情况执行),在每一个情况内部:调用函数自己
2.基于递归的求解代码:
# 1.表示迷宫 maze抽象化形成矩阵
#2.利用好递归性质
maze=[[0,0,1,1,1],[1,0,1,0,0],[0,0,1,0,0],[1,0,0,1,0],[0,0,0,0,0],[0,1,1,0,1]]
def mark(maze,pos):
maze[pos[0]][pos[1]]=2
def findit(maze,start,end):
dir1=((-1,0),(0,1),(1,0),(0,-1))
#print("调用了几次find每次的起点是:",start)
if start==end:
print(start) # 注意这里是无法返回值的
else:
mark(maze,start)
start1=start[:] # 这里最容易写成 star1=start
#print("出现一次")
for i in range(0,4):
# print("四个方向 ",start1)
start[0]=start1[0] # 用于保留本次循环起点
start[1]=start1[1]
(start[0],start[1])=(start[0]+dir1[i][0],start[1]+dir1[i][1])
#print("最后",start)
if 0<=start[0]<=len(maze)-1 and 0<=start[1]<=len(maze[0])-1:
if maze[start[0]][start[1]]==0:
findit(maze,start,end)
findit(maze,[1,3],[5,3])
3. 基于堆栈的非递归深度优先方法
#利用栈的回溯法,(递归的人工实现)
maze=[[0,0,1,1,1],[1,0,1,0,0],[0,0,1,0,0],[1,0,0,1,0],[0,0,0,0,0],[0,1,1,0,1]]
def mark(maze,pos):
maze[pos[0]][pos[1]]=2
def findit(maze,pos,end): # 参数 迷宫矩阵 运动点 终点
dir1=((-1,0),(0,1),(1,0),(0,-1)) # 吓一跳参数
st= []
if pos==end:
return pos
else:
mark(maze,pos)
st.append(pos)
while st: # 总体就是 先画出操作图,在根据图来把控程序
pos=st.pop()
pos1=pos[:] # 这个细节要注意
for i in range(4):
pos=pos1[:] # 要注意
pos[0],pos[1]=pos[0]+dir1[i][0],pos[1]+dir1[i][1]
#print("四个方向",pos)
if 0<=pos[0]<=len(maze)-1 and 0<=pos[1]<=len(maze[0])-1:
if maze[pos[0]][pos[1]]==0:
if pos==end:
return end
else:
mark(maze,pos)
print("1,4",pos)
st.append(pos)
print("没有找到")
findit(maze,[1,4],[1,3])
4. 基于队列的广度优先算法实现
# 基于队列的广度优先
from queue import Queue # 注意命名模块时不要用预留字
maze=[[0,0,1,1,1],[1,0,1,0,0],[0,0,1,0,0],[1,0,0,1,0],[0,0,0,0,0],[0,1,1,0,1]]
def mark(maze,pos):
maze[pos[0]][pos[1]]=2
def findit(maze,pos,end):
que=Queue()
dir1=((-1,0),(0,1),(1,0),(0,-1)) # 吓一跳参数
if pos==end:
return pos
else:
que.put(pos)
while not que.empty():
pos1=que.get()
#print(pos1)
mark(maze,pos1)
for i in range(4):
pos=pos1[:]
pos[0],pos[1]=pos[0]+dir1[i][0],pos[1]+dir1[i][1]
if 0<=pos[0]<=len(maze)-1 and 0<=pos[1]<=len(maze[0])-1:
if maze[pos[0]][pos[1]]==0:
if pos==end:
return pos
else:
que.put(pos)
print("没有找到")
ans=findit(maze,[1,3],[0,1])
print(ans)