一、迷宫问题
给一个二维列表,表示迷宫(0表示通道,1表示围墙)。给出算法,求一条走出迷宫的路径。
maze = [ [1,1,1,1,1,1,1,1,1,1], [1,0,0,1,0,0,0,1,0,1], [1,0,0,1,0,0,0,1,0,1], [1,0,0,0,0,1,1,0,0,1], [1,0,1,1,1,0,0,0,0,1], [1,0,0,0,1,0,0,0,0,1], [1,0,1,0,0,0,1,0,0,1], [1,0,1,1,1,0,1,1,0,1], [1,1,0,0,0,0,0,0,0,1], [1,1,1,1,1,1,1,1,1,1] ]
1代表墙,0代表路,图示如下:
二、栈——深度优先搜索
应用栈解决迷宫问题,叫做深度优先搜索(一条路走到黑),也叫做回溯法。
1、用栈解决的思路
思路:从上一个节点开始,任意找下一个能走的点,当找不到能走的点时,退回上一个点寻找是否有其他方向的点。
使用栈存储当前路径。后进先出,方便回退到上一个点。
2、用栈代码实现
maze = [ [1,1,1,1,1,1,1,1,1,1], [1,0,0,1,0,0,0,1,0,1], [1,0,0,1,0,0,0,1,0,1], [1,0,0,0,0,1,1,0,0,1], [1,0,1,1,1,0,0,0,0,1], [1,0,0,0,1,0,0,0,0,1], [1,0,1,0,0,0,1,0,0,1], [1,0,1,1,1,0,1,1,0,1], [1,1,0,0,0,0,0,0,0,1], [1,1,1,1,1,1,1,1,1,1] ] # 四个移动方向 dirs = [ lambda x,y: (x+1, y), # 下 lambda x,y: (x-1, y), # 上 lambda x,y: (x, y-1), # 左 lambda x,y: (x, y+1) # 右 ] def maze_path(x1, y1, x2, y2): # (x1,y1)代表起点;(x2,y2)代表终点 stack = [] stack.append((x1, y1)) while(len(stack)>0): curNode = stack[-1] # 当前的节点(栈顶) if curNode[0] ==x2 and curNode[1] == y2: # 判断是否走到终点 # 走到终点,遍历栈输出路线 for p in stack: print(p) return True """搜索四个方向""" for dir in dirs: nextNode = dir(curNode[0], curNode[1]) # 如果下一个阶段能走 if maze[nextNode[0]][nextNode[1]] == 0: stack.append(nextNode) # 将节点加入栈 maze[nextNode[0]][nextNode[1]] = 2 # 将走过的这个节点标记为2表示已经走过了 break # 找到一个能走的点就不再遍历四个方向 else: # 一个都找不到,将该位置标记并该回退 maze[nextNode[0]][nextNode[1]] = 2 stack.pop() else: print("没有路") return False maze_path(1,1,8,8) """ (1, 1) (2, 1) (3, 1) (4, 1) (5, 1) (5, 2) (5, 3) (6, 3) (6, 4) (6, 5) (7, 5) (8, 5) (8, 6) (8, 7) (8, 8) """
总结算法就是:创建一个空栈,首先将入口位置进栈。当栈不空时循环:获取栈顶元素,寻找下一个可走的相邻方块,如果找不到可走的相邻方块,说明当前位置是死胡同,进行回溯(就是讲当前位置出栈,看前面的点是否还有别的出路)
使用栈来解决迷宫问题,虽然实现起来比较简单,但是它的路径并不是最短的,很可能会绕远,如果想走最短路径可以使用队列来做。
三、队列——广度优先搜索
应用队列解决迷宫问题,叫做广度优先搜索。