栈和队列的应用——迷宫问题

给一个二维列表,表示迷宫(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]
      ]
#封装一个列表表示四个位置表达式
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
        #(x,y)四个方向:上:(x-1,y),下:(x+1,y),左:(x,y-1),右:(x,y+1)
        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#能找到一个就break
        else:#如果没有找到出栈再找
                maze[nextNode[0]][nextNode[1]]=2
                stack.pop()
    else:
        print("没有路")
        return False
maze_path(1,1,8,8)

问题:路径不一定是最短的
队列——广度优先搜索
思路:从一个节点开始,寻找所有接下来能继续走的点,继续不断寻找,知道找到出口。使用队列存储当前正在考虑的节点

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 print_r(path):
    real_path=[]
    i=len(path)-1
    while i>=0:
        real_path.append(path[i][0:2])
        i=path[i][2]
    real_path.reverse()
    for node in real_path:
        print(node)
        
def maze_path_queue(x1,y1,x2,y2):
    #定义一个队列
    queue=deque()
    path=[]
    queue.append((x1,y1,-1))#起点进队,-1表示吧位置x1,y1带进来的节点的位置
    while len(queue)>0:#当队列不空时循环
        cur_node=queue.popleft()
        path.append(cur_node)
        if cur_node[0]==x2 and cur_node[1]==y2:
            #到达终点
            print(path)
            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))#len(path)-1表示cur_node的位置
                maze[next_node[0]][next_node[1]]=2#走过以后标记为2
    return False
 
maze_path_queue(1,1,8,8)


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章