5.算法之栈和队列之迷宫求解算法

1.特点及常用命令

栈特点先进后出,后进先出。(常用命令)

list=[1,2,3,4,5]
list.append(6)   #进栈
list.pop()   #出栈
list[-1]    #查看栈顶

队列特点先进先出,后进后出。(双向队列常用命令)

from collections import deque  #导入库
 queue=deque()                 #创建双向队列
 queue.append(1)               #从队尾进入队列
 queue.popleft()               #从队首删除元素,即出队
 queue.appendleft(2)           #从队首进队
 queue.pop()                   #从队尾删除元素,即出队

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, 1, 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]]


def maze_path(x1, y1, x2, y2):
    stack = []
    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)]              #定义寻找路径顺序
    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[0], nextnode[1]))   #如果可以走,将这个点加入栈
                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)

队列的解法(结果是一定是最短的之一)——广度优先搜索

# 开发时间: 15:37
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, 0, 0, 0, 0, 0, 0, 1],
        [1, 0, 0, 0, 0, 1, 1, 0, 0, 1],
        [1, 0, 1, 1, 1, 0, 0, 1, 0, 1],
        [1, 0, 1, 0, 1, 0, 0, 0, 0, 1],
        [1, 0, 0, 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]]
def print_r(path):                          #打印路径函数
    curnode=path[-1]                        #将终点读出
    realpath=[]                             #存储真实路径
    while curnode[2] != -1:                 #判断是否寻找到了起点
        realpath.append(curnode[0:2])       #将真实路径加入realpath,可以使用appendleft 这样就可以不用反转了
        curnode=path[curnode[2]]            #追溯上一个点
    realpath.append(curnode[0:2])           #将起点加入路径
    realpath.reverse()                      #因为从终点往起点寻找的,所以要反转
    for node in realpath:                   #打印路径
         print(node)


def maze_path_queue(x1, y1, x2, y2):

    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)]          #寻找方向函数
    queue = deque()                           #创建队列
    queue.append((x1,y1,-1))                  #将初试位置加入队列,并将由谁找到的这个位置存到第三个参数上
    path=[]
    while len(queue)>0:
        curnode=queue.popleft()               #读出当前点并从队列删除
        path.append(curnode)                  #存储走过的所有点,并可追溯
        if curnode[0]==x2 and curnode[1]==y2: #判断是否到达终点
            print_r(path)
            return True
        for dir in dirs:                            #寻找这个点下个点所有可走的方向
            nextnode=dir(curnode[0],curnode[1])
            if maze[nextnode[0]][nextnode[1]] == 0:
                queue.append((nextnode[0],nextnode[1],len(path)-1))  #将这个点加入队列,并将这个点由那个点走来的path中的索引记录
                maze[nextnode[0]][ nextnode[1]] = 2                   #标记走过

    else:
        print('没有路')
        return  False
maze_path_queue(1,1,2,8)

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值