队列与栈解决迷宫问题(待补充)
内容概要
一、迷宫问题介绍
二、栈解决迷宫问题
三、队列解决迷宫问题
1、迷宫问题介绍
迷宫问题简单的说,就是通过一种算法,让计算机找到出口
迷宫可以通过二级列表实现,1表示路不允许通过;0表示路允许通过
比如下面的二级列表表示的迷宫
maze = [ # 横是y轴,纵是x轴 [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, 0, 1, 1, 0, 1], [1, 1, 0, 1, 1, 1, 1, 0, 0, 1], [1, 0, 0, 0, 1, 1, 0, 0, 0, 1], [1, 0, 1, 0, 1, 0, 0, 0, 0, 1], [1, 0, 1, 0, 0, 0, 1, 1, 0, 1], [1, 0, 1, 1, 1, 0, 0, 0, 0, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], ]
解决迷宫问题有两种思路,一种是使用栈;另一种是使用队列
2、栈解决迷宫问题
栈解决迷宫问题,遵照深度优先。
也就是说一条路走到底,如果没能到达终点或者没有路走,那么就开始回溯,找到另外一条可以走的路。
栈解决迷宫问题代码实现
思路
(1)规定迷宫,迷宫的起点、终点
(2)创建栈,栈用于存储相关的路径坐标
(3)检查栈顶(所在迷宫的当前位置)的四个方向,只要有可通行的节点,将该节点进栈,重复步骤3
(4)如果四个方向都不能同行,并且没有到达终点,那么是死路,进行回退,栈顶出栈
(5)重复步骤3(特别要注意的是,想办法识别之前去过的节点,使得不再重复死路)
(6)找到终点
需要注意的是:
(1)如果不存在到达终点的路径,那么栈最终栈会变为空
(2)回退时,要使锝不再重复去过的路径,可以将去过的路径进行标记,告诉计算机这条路不通
(3)栈寻路是深度优先,找到的路径并非一定是最短的
代码实现
li = [ lambda x, y: (x, y+1), lambda x, y: (x+1, y), lambda x, y: (x, y-1), lambda x, y: (x-1, y), ] def search_path(maze, x1, y1, x2, y2): # x1, y1是起点坐标;x2, y2是终点坐标 stack = [(x1, y1)] # 使用列表充当一个栈,初始存有起点 while stack: # 栈空时,说明没有路径 node = stack[-1] if node[0] == x2 and node[1] == y2: # 查看栈顶是否是终点 for node in stack: print(node) break for func in li: # 检查4个方向是否可通过 next_node = func(node[0], node[1]) if maze[next_node[0]][next_node[1]] == 0: maze[node[0]][node[1]] = 2 # 将前一个节点标记为已走过,避免回到之前的节点,陷入死循环 stack.append(next_node) # 更新所在位置 break else: maze[node[0]][node[1]] = 2 # 当四个方向都不可通行时,将所在位置设置为无法通行 stack.pop() # 回到上一个位置 else: print("没有路径!") search_path(maze, 1, 1, 8, 8)
3、队列解决迷宫问题
队列解决迷宫问题思路
**思路图解**
自己尝试写的代码(只实现了功能,并且似乎没有使用队列)

func_li = [ lambda x, y: (x, y+1), lambda x, y: (x+1, y), lambda x, y: (x, y-1), lambda x, y: (x-1, y), ] def search_path(maze, x1, y1, x2, y2): nodes = [(x1, y1)] maze[x1][y1] = 2 next_nodes = [] count = 3 n = 1 while len(nodes): for node in nodes: for func in func_li: next_node = func(node[0], node[1]) if next_node[0] == x2 and next_node[1] == y2: result_node = [next_node] node = next_node # while count > 2: while not (node[0] == x1 and node[1] == y1): for fu in func_li: previous_node = fu(node[0], node[1]) if maze[previous_node[0]][previous_node[1]] == count-1: result_node.append(previous_node) node = previous_node count -= 1 print(1) break print(result_node) else: # result_node.append((x1, y1)) return result_node if maze[next_node[0]][next_node[1]] == 0: next_nodes.append(next_node) maze[next_node[0]][next_node[1]] = count tmp = nodes nodes = next_nodes next_nodes = tmp next_nodes.clear() count += 1 for li in maze: print(li) print("=================={}===================".format(n)) n += 1 else: print("不存在路径!") re_li = search_path(maze, 1, 1, 8, 8) print(re_li)
优化

def search_path(maze, x1, y1, x2, y2): nodes = [(x1, y1)] # 定义一个列表用于存储本次需要探寻的节点 next_nodes = [] # 将由nodes探寻得到的可通过节点存储到next_nodes中 maze[x1][y1] = 2 # 将起点设置为已走 mark = 3 # 动态标记已经走过的节点 while len(nodes): for node in nodes: for func in li: next_node = func(node[0], node[1]) # 判断终点和返回路径机制 if next_node[0] == x2 and next_node[1] == y2: # 判断节点是否为终点 result_node = [next_node] # 存储最终路径的列表,初始值为终点坐标 node = next_node while not (node[0] == x1 and node[1] == y1): # 这里最难了,找到终点后要进行回溯,从终点节点按照之前设置的动态标记找回起点 for fu in li: previous_node = fu(node[0], node[1]) if maze[previous_node[0]][previous_node[1]] == mark-1: # 根据标记找到正确的前一个节点 result_node.append(previous_node) node = previous_node mark -= 1 # 下一个标记的值比此次标记值小1 break else: result_node.reverse() # 由于是从终点回退到起点,所以最终的列表循序是反的 return result_node if maze[next_node[0]][next_node[1]] == 0: # 判断该节点是否可以通过 next_nodes.append(next_node) maze[next_node[0]][next_node[1]] = mark tmp = nodes nodes = next_nodes next_nodes = tmp next_nodes.clear() mark += 1 # 标记值自增,用于区分不同次的遍历 # 查看标记 # for line in maze: # print(line) # print() else: print("不存在路径!")
牛逼的清华大佬的牛逼代码
from collections import deque def search_path_queue(maze, x1, y1, x2, y2): global cur_node queue = deque([(x1, y1, -1)]) # 与自己的思路不同的是,大佬将用于找到上一个节点的标记添加每个节点里 path = [] while len(queue) > 0: node = queue.pop() path.append(node) for func in li: next_node = func(node[0], node[1]) if maze[next_node[0]][next_node[1]] == 0: cur_node = (next_node[0], next_node[1], len(path) - 1) queue.append(cur_node) maze[next_node[0]][next_node[1]] = 2 if next_node[0] == x2 and next_node[1] == y2: result_li = [] node = queue.pop() while node[2] != -1: result_li.append((node[0], node[1])) node = path[node[2]] else: result_li.append((x1, y1)) result_li.reverse() return result_li else: print("没有路径!")
***待补充***
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构