美文网首页
使用栈解决简单迷宫

使用栈解决简单迷宫

作者: listems | 来源:发表于2023-03-21 13:10 被阅读0次

用二维列表模拟迷宫,1代表墙,0代表当前路是可以通过的
回溯法的核心是状态的转换,当当前状态不能进入下一状态,我们就回溯到之前能进入下一状态的某状态结点,我们用栈的append和pop去模拟这一过程

# 起始位置为(1, 1)  终点位置为(8, 8)
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]
]

首先我们定义一个函数,函数的参数分别为起始位置终点位置

def path(x1, y1, x2, y2):
    pass
path(1, 1, 8, 8)

我们定义当前状态位置向四个方向转移的函数, 用python的λ函数来实习

directions = [
    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 path(x1, y1, x2, y2):
    stack = []
    stack.append((x1, y1))
    while len(stack) > 0:
        # 当前状态
        cur_node = stack[-1]
        # 终止状态
        if cur_node[0] == x2 and cur_node[1] == y2:
            return True
            pass
    # 当栈为空时 说明为死路 走不到终点
    else:
        return False

接下来我们定义下一状态next_node通过四个方向的函数不断的判断是否能通过 如果四个方向皆不能满足条件则利用stack的pop操作回溯到之前的某一能使条件满足的状态, 为防止环路的出现,每次访问过的路径都设置为已访问状态。

 for direction in directions:
            # 下一状态
            next_node = direction(cur_node[0], cur_node[1])
            if maze[next_node[0]][next_node[1]] == 0:
                stack.append(next_node)
                maze[next_node[0]][next_node[1]] = 2  # 把访问过的路径置为已访问
                break     # 每成功一次就立刻进入下一次状态的寻找
        # 如果四个方向皆不成立 回溯到之前的状态 直到有条件满足当前状态
        else:
            # 利用栈的pop操作进行回溯
            stack.pop()
            maze[next_node[0]][next_node[1]] = 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, 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]
]

directions = [
    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 path(x1, y1, x2, y2):
    stack = []
    stack.append((x1, y1))
    while len(stack) > 0:
        # 当前状态
        cur_node = stack[-1]
        if cur_node[0] == x2 and cur_node[1] == y2:
            for pat in stack:
                print(pat)
            return True
        print(stack)
        for direction in directions:
            # 下一状态
            next_node = direction(cur_node[0], cur_node[1])
            if maze[next_node[0]][next_node[1]] == 0:
                stack.append(next_node)
                maze[next_node[0]][next_node[1]] = 2  # 把访问过的路径置为已访问
                break     # 每成功一次就立刻进入下一次状态的寻找
        # 如果四个方向皆不成立 回溯到之前的状态 直到有条件满足当前状态
        else:
            # 利用栈的pop操作进行回溯
            stack.pop()
            maze[next_node[0]][next_node[1]] = 2
    # 当栈为空时 说明为死路 走不到终点
    else:
        return False
print(path(1, 1, 8, 8))

某一可达到终点的路径

(1, 1)
(2, 1)
(1, 1)
(1, 2)
(2, 2)
(3, 2)
(3, 1)
(4, 1)
(5, 1)
(5, 2)
(5, 3)
(6, 3)
(6, 4)
(6, 5)
(5, 5)
(4, 5)
(4, 6)
(5, 6)
(5, 7)
(4, 7)
(3, 7)
(3, 8)
(4, 8)
(5, 8)
(6, 8)
(7, 8)
(8, 8)

可以通过打印栈的增长和减小过程来感受不停寻找下一状态和回溯的过程

print(stack)
[(1, 1)]
[(1, 1), (2, 1)]
[(1, 1), (2, 1), (1, 1)]
[(1, 1), (2, 1), (1, 1), (1, 2)]
[(1, 1), (2, 1), (1, 1), (1, 2), (2, 2)]
[(1, 1), (2, 1), (1, 1), (1, 2), (2, 2), (3, 2)]
[(1, 1), (2, 1), (1, 1), (1, 2), (2, 2), (3, 2), (3, 1)]
[(1, 1), (2, 1), (1, 1), (1, 2), (2, 2), (3, 2), (3, 1), (4, 1)]
[(1, 1), (2, 1), (1, 1), (1, 2), (2, 2), (3, 2), (3, 1), (4, 1), (5, 1)]
[(1, 1), (2, 1), (1, 1), (1, 2), (2, 2), (3, 2), (3, 1), (4, 1), (5, 1), (6, 1)]
[(1, 1), (2, 1), (1, 1), (1, 2), (2, 2), (3, 2), (3, 1), (4, 1), (5, 1), (6, 1), (7, 1)]
[(1, 1), (2, 1), (1, 1), (1, 2), (2, 2), (3, 2), (3, 1), (4, 1), (5, 1), (6, 1)]
[(1, 1), (2, 1), (1, 1), (1, 2), (2, 2), (3, 2), (3, 1), (4, 1), (5, 1)]
[(1, 1), (2, 1), (1, 1), (1, 2), (2, 2), (3, 2), (3, 1), (4, 1), (5, 1), (5, 2)]
[(1, 1), (2, 1), (1, 1), (1, 2), (2, 2), (3, 2), (3, 1), (4, 1), (5, 1), (5, 2), (5, 3)]
[(1, 1), (2, 1), (1, 1), (1, 2), (2, 2), (3, 2), (3, 1), (4, 1), (5, 1), (5, 2), (5, 3), (6, 3)]
[(1, 1), (2, 1), (1, 1), (1, 2), (2, 2), (3, 2), (3, 1), (4, 1), (5, 1), (5, 2), (5, 3), (6, 3), (6, 4)]
[(1, 1), (2, 1), (1, 1), (1, 2), (2, 2), (3, 2), (3, 1), (4, 1), (5, 1), (5, 2), (5, 3), (6, 3), (6, 4), (6, 5)]
[(1, 1), (2, 1), (1, 1), (1, 2), (2, 2), (3, 2), (3, 1), (4, 1), (5, 1), (5, 2), (5, 3), (6, 3), (6, 4), (6, 5), (5, 5)]
[(1, 1), (2, 1), (1, 1), (1, 2), (2, 2), (3, 2), (3, 1), (4, 1), (5, 1), (5, 2), (5, 3), (6, 3), (6, 4), (6, 5), (5, 5), (4, 5)]
[(1, 1), (2, 1), (1, 1), (1, 2), (2, 2), (3, 2), (3, 1), (4, 1), (5, 1), (5, 2), (5, 3), (6, 3), (6, 4), (6, 5), (5, 5), (4, 5), (4, 6)]
[(1, 1), (2, 1), (1, 1), (1, 2), (2, 2), (3, 2), (3, 1), (4, 1), (5, 1), (5, 2), (5, 3), (6, 3), (6, 4), (6, 5), (5, 5), (4, 5), (4, 6), (5, 6)]
[(1, 1), (2, 1), (1, 1), (1, 2), (2, 2), (3, 2), (3, 1), (4, 1), (5, 1), (5, 2), (5, 3), (6, 3), (6, 4), (6, 5), (5, 5), (4, 5), (4, 6), (5, 6), (5, 7)]
[(1, 1), (2, 1), (1, 1), (1, 2), (2, 2), (3, 2), (3, 1), (4, 1), (5, 1), (5, 2), (5, 3), (6, 3), (6, 4), (6, 5), (5, 5), (4, 5), (4, 6), (5, 6), (5, 7), (4, 7)]
[(1, 1), (2, 1), (1, 1), (1, 2), (2, 2), (3, 2), (3, 1), (4, 1), (5, 1), (5, 2), (5, 3), (6, 3), (6, 4), (6, 5), (5, 5), (4, 5), (4, 6), (5, 6), (5, 7), (4, 7), (3, 7)]
[(1, 1), (2, 1), (1, 1), (1, 2), (2, 2), (3, 2), (3, 1), (4, 1), (5, 1), (5, 2), (5, 3), (6, 3), (6, 4), (6, 5), (5, 5), (4, 5), (4, 6), (5, 6), (5, 7), (4, 7), (3, 7), (3, 8)]
[(1, 1), (2, 1), (1, 1), (1, 2), (2, 2), (3, 2), (3, 1), (4, 1), (5, 1), (5, 2), (5, 3), (6, 3), (6, 4), (6, 5), (5, 5), (4, 5), (4, 6), (5, 6), (5, 7), (4, 7), (3, 7), (3, 8), (2, 8)]
[(1, 1), (2, 1), (1, 1), (1, 2), (2, 2), (3, 2), (3, 1), (4, 1), (5, 1), (5, 2), (5, 3), (6, 3), (6, 4), (6, 5), (5, 5), (4, 5), (4, 6), (5, 6), (5, 7), (4, 7), (3, 7), (3, 8), (2, 8), (1, 8)]
[(1, 1), (2, 1), (1, 1), (1, 2), (2, 2), (3, 2), (3, 1), (4, 1), (5, 1), (5, 2), (5, 3), (6, 3), (6, 4), (6, 5), (5, 5), (4, 5), (4, 6), (5, 6), (5, 7), (4, 7), (3, 7), (3, 8), (2, 8)]
[(1, 1), (2, 1), (1, 1), (1, 2), (2, 2), (3, 2), (3, 1), (4, 1), (5, 1), (5, 2), (5, 3), (6, 3), (6, 4), (6, 5), (5, 5), (4, 5), (4, 6), (5, 6), (5, 7), (4, 7), (3, 7), (3, 8)]
[(1, 1), (2, 1), (1, 1), (1, 2), (2, 2), (3, 2), (3, 1), (4, 1), (5, 1), (5, 2), (5, 3), (6, 3), (6, 4), (6, 5), (5, 5), (4, 5), (4, 6), (5, 6), (5, 7), (4, 7), (3, 7), (3, 8), (4, 8)]
[(1, 1), (2, 1), (1, 1), (1, 2), (2, 2), (3, 2), (3, 1), (4, 1), (5, 1), (5, 2), (5, 3), (6, 3), (6, 4), (6, 5), (5, 5), (4, 5), (4, 6), (5, 6), (5, 7), (4, 7), (3, 7), (3, 8), (4, 8), (5, 8)]
[(1, 1), (2, 1), (1, 1), (1, 2), (2, 2), (3, 2), (3, 1), (4, 1), (5, 1), (5, 2), (5, 3), (6, 3), (6, 4), (6, 5), (5, 5), (4, 5), (4, 6), (5, 6), (5, 7), (4, 7), (3, 7), (3, 8), (4, 8), (5, 8), (6, 8)]
[(1, 1), (2, 1), (1, 1), (1, 2), (2, 2), (3, 2), (3, 1), (4, 1), (5, 1), (5, 2), (5, 3), (6, 3), (6, 4), (6, 5), (5, 5), (4, 5), (4, 6), (5, 6), (5, 7), (4, 7), (3, 7), (3, 8), (4, 8), (5, 8), (6, 8), (7, 8)]
[(1, 1), (2, 1), (1, 1), (1, 2), (2, 2), (3, 2), (3, 1), (4, 1), (5, 1), (5, 2), (5, 3), (6, 3), (6, 4), (6, 5), (5, 5), (4, 5), (4, 6), (5, 6), (5, 7), (4, 7), (3, 7), (3, 8), (4, 8), (5, 8), (6, 8), (7, 8), (8, 8)]

相关文章

  • 使用栈解决迷宫问题(深度优先遍历)

    问题描述: 有如图所示迷宫,设计一个算法,找出一条从入口到出口的路径。 思路分析: 我们使用一个二维数组模拟迷宫,...

  • 用栈解决迷宫问题

    转载https://blog.csdn.net/zhouchenghao123/article/details/8...

  • 算法-迷宫问题(递归)

    迷宫问题:之前只用栈来实现,现在使用递归来实现。blog.csdn.net/feixiaoxing/article...

  • LeetCode 栈、队列、优先队列专题 1:栈和队列的使用

    这一部分,我们开始介绍“栈、队列、优先队列”。栈和队列虽然是简单的数据结构,但是使用这些简单的数据结构所解决的算法...

  • 文章结构 栈是什么 Java中的Stack源码分析 什么时候使用栈 应用实例:使用栈来解决表达式计算问题 1、栈是...

  • 数据结构复习

    第三章 栈和队列 一 栈 栈的类型 顺序栈 链式栈 双向栈 栈的应用 数制转换 行编辑程序 迷宫求解 表达式求值:...

  • LeetCode 每日一题 [12] 用队列实现栈

    LeetCode 用队列实现栈 [简单] 使用队列实现栈的下列操作: push(x) -- 元素 x 入栈pop(...

  • Object-c 使用栈实现迷宫

    关于本例子中用到的栈结构请参看:https://www.jianshu.com/p/c941b224a69d 迷宫...

  • LeetCode-20 有效的括号

    题目:20. 有效的括号 难度:简单 分类:栈 解决方案:入栈出栈 今天我们学习第20题有效的括号,这是一道关于栈...

  • 栈的特点和使用场景

    前言 本篇文章主要解决如下问题: 栈的特点是什么? 使用栈的问题场景一般都可以使用数组或者链表解决,那么我们为什么...

网友评论

      本文标题:使用栈解决简单迷宫

      本文链接:https://www.haomeiwen.com/subject/vddmrdtx.html