在迷宫问题中,栈和队列是两种不同的数据结构,它们可以用于构建不同的迷宫通路。栈遵循后进先出(LIFO)原则,使用栈解决迷宫问题是深度优先搜索(DFS)的一种实现;而队列遵循先进先出(FIFO)原则,使用队列解决迷宫问题是广度优先搜索(BFS)的一种实现。
### 栈解决迷宫问题(深度优先搜索)
深度优先搜索从起点开始,沿着一条路径尽可能深地探索,直到无法继续,然后回溯到上一个岔路口,尝试另一条路径。
```python
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):
stack = []
stack.append((x1, y1))
while len(stack) > 0:
curNode = stack[-1]
if curNode[0] == x2 and curNode[1] == y2:
print(stack)
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 # 标记为已经走过
break
else:
stack.pop()
print("There is no way.")
return False
maze_path(1, 1, 8, 8)
```
这种方法找到的可能不是最优解,但可以在找到一条路径后,回溯继续寻找其他路径,从而输出所有解[^3]。
### 队列解决迷宫问题(广度优先搜索)
广度优先搜索从起点开始,逐层地探索所有可能的路径,先探索距离起点最近的所有节点,再依次向外扩展。
```python
from collections import deque
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_queue(x1, y1, x2, y2):
queue = deque()
queue.append((x1, y1, None))
visited = set()
visited.add((x1, y1))
while queue:
curNode = queue.popleft()
if curNode[0] == x2 and curNode[1] == y2:
path = []
while curNode:
path.append((curNode[0], curNode[1]))
curNode = curNode[2]
path.reverse()
print(path)
return True
for dir in dirs:
nextNode = dir(curNode[0], curNode[1])
if maze[nextNode[0]][nextNode[1]] == 0 and nextNode not in visited:
queue.append((nextNode[0], nextNode[1], curNode))
visited.add(nextNode)
print("There is no way.")
return False
maze_path_queue(1, 1, 8, 8)
```
由于所有路径是同时探索的,所以先找到终点的那条路径一定是最短的[^1]。