栈的应用-迷宫问题
给一个二维列表,表示迷宫(0表示通道,1表示围墙),给出算法,求一条走出迷宫的路径。
from collections import deque 两种思路:基于堆栈、基于队列
基于堆栈:在一个迷宫节点(x,y)上,可以进行四个方向的探查:maze[x-1][y],maze[x+1][y],maze[x][y-1],maze[x][y+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] ] dirs = [ lambda x,y:(x-1,y), #上 lambda x,y:(x,y+1), #右 lambda x,y:(x+1,y), #下 lambda x,y:(x,y-1), #左 ] def solve_maze(x1, y1, x2, y2):
"""基于栈实现""" stack = [] stack.append((x1,y1)) maze[x1][y1] = 2 while len(stack) > 0: # 当栈不空循环 cur_node = stack[-1] if cur_node == (x2,y2): #到达终点 for p in stack: print(p) return True for dir in dirs: next_node = dir(*cur_node) if maze[next_node[0]][next_node[1]] == 0: #找到一个能走的方向 stack.append(next_node) maze[next_node[0]][next_node[1]] = 2 # 2表示已经走过的点 break else: #如果一个方向也找不到 stack.pop() else: print("无路可走") return False def solve_maze2(x1,y1,x2,y2):
"""基于队列来实现""" queue = deque() path = [] # 记录出队之后的节点 queue.append((x1,y1,-1)) maze[x1][y1] = 2 while len(queue) > 0: cur_node = queue.popleft() path.append(cur_node) if cur_node[0] == x2 and cur_node[1] == y2: #到终点 real_path = [] x,y,i = path[-1] real_path.append((x,y)) while i >= 0: node = path[i] real_path.append(node[0:2]) i = node[2] real_path.reverse() for p in real_path: print(p) return True for dir in dirs: next_node = dir(cur_node[0], cur_node[1]) if maze[next_node[0]][next_node[1]] == 0: queue.append((next_node[0], next_node[1], len(path)-1)) maze[next_node[0]][next_node[1]] = 2 # 标记为已经走过 else: print("无路可走") return False solve_maze2(1,1,8,8) #输入起点的位置和终点的位置
。。。。。。。。。。有时间更新