基于Python3的数据结构与算法 - 15 栈和队列的应用(迷宫问题)

题目

给一个二维列表,表示迷宫(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, 1, 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):  # 表示起点和终点的位置,x表示列,y表示行
    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  # 找到后返回True
        # x,y 上下左右的四个方向为x+1, x-1, y+1, y-1
        for dic in dirs:
            nextNode = dic(curNode[0], curNode[1])  # 下一个节点的位置
            if maze[nextNode[0]][nextNode[1]] == 0:  # 下一个节点能走
                stack.append(nextNode)
                maze[nextNode[0]][nextNode[1]] = 2   # 将该点位置标记为2表示已经走过,
                break         # 遍历4个方向找是否能走的,找到一个就退出
        else:  # 如果没找到,先将走过的标记为2
            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):
    curNode = path[-1]  # z 最后一个节点

    realpath = []

    while curNode[2] != -1:
        realpath.append((curNode[0:2]))
        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):
    queue = deque()
    queue.append((x1, y1, -1))  # 起点从-1来
    path = []  # 用于储存curNode的位置
    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])  # 使用nextNode将下一个位置的坐标存起来
            if maze[nextNode[0]][nextNode[1]] == 0:  # 表示下一个坐标能走
                queue.append((nextNode[0], nextNode[1], len(path) - 1))  # 后续点进队,记录那哪个节点由谁带来的;上一个位置的坐标就是path的最后一个元素的下标
                maze[nextNode[0]][nextNode[1]] = 2  # 走过的点标记为2
    else:
        print("没有路")
        return False


maze_path_queue(1, 1, 8, 8)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/449783.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

OpenCV开发笔记(七十七):相机标定(二):通过棋盘标定计算相机内参矩阵矫正畸变摄像头图像

若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/136616551 各位读者,知识无穷而人力有穷,要么改需求,要么找专业人士,要么自己研究 红胖子(红模仿)的博…

基于Java+SpringBoot+vue+element实现汽车订票管理平台详细设计和实现

基于JavaSpringBootvueelement实现汽车订票管理平台详细设计和实现 博主介绍:多年java开发经验,专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 …

开源好用的所见即所得(WYSIWYG)编辑器:Editor.js

文章目录 特点基于区块干净的数据 界面与交互插件标题和文本图片列表Todo表格 使用安装创建编辑器实例配置工具本地化自定义样式 今天介绍一个开源好用的Web所见即所得(WYSIWYG)编辑器: Editor.js Editor.js 是一个基于 Web 的所见即所得富文本编辑器,它…

【毕设级项目】基于AI技术的多功能消防机器人(完整工程资料源码)

基于AI技术的多功能消防机器人演示效果 竞赛-基于AI技术的多功能消防机器人视频演示 前言 随着“自动化、智能化”成为数字时代发展的关键词,机器人逐步成为社会经济发展的重要主体之一,“机器换人”成为发展的全新趋势和时代潮流。在可预见的将来&#…

鸿蒙App基础

基础说明 .1、应用模型 .1.1、构成要素 应用组件 应用组件是应用的基本组成单位,是应用的运行入口。用户启动、使用和退出应用过程中,应用组件会在不同的状态间切换,这些状态称为应用组件的生命周期。应用组件提供生命周期的回调函数&…

如何提高API接口的性能和设计安全可靠的API

如何提高API接口的性能 下图显示了提高 API 性能的 5 种常见技巧。 分页 这是在结果集较大时常用的优化方法。结果会以流式方式传回客户端,以提高服务响应速度。 异步日志 同步日志每次调用都要处理磁盘,会降低系统速度。异步日志会先将日志发送到无…

力扣226.翻转二叉树(二叉树的先序遍历)

文章目录 题目描述思路复杂度Code 题目描述 思路 利用二叉树的先序遍历,每次递归遍历时将当前节点的左右子节点交换即可 复杂度 时间复杂度: O ( n ) O(n) O(n);其中 n n n为树节点的个数 空间复杂度: O ( h e i g h ) O(heigh) O(heigh);其…

任务执行中拖延的认知神经机制

任务执行中拖延的认知神经机制 引言 虽然动机的产生往往是人们行动的前提(Ajzen, 2011;林琳&白新文,2014),但动机的产生却并不必然地导致随后的行为(Rhodes&deBruijn,2013;Sniehotta, Scho1z, & Schwarzer, 2005)。动机向行为的转换依赖于一系列自我控…

北京市行政村边界shp数据/北京市乡镇边界/北京市土地利用分类数据

北京是一座有着三千多年历史的古都,在不同的朝代有着不同的称谓,大致算起来有二十多个别称。北京地势西北高、东南低。西部、北部和东北部三面环山,东南部是一片缓缓向渤海倾斜的平原。境内流经的主要河流有:永定河、潮白河、北运…

Ollama 只安装 Ollama,本地快速部署谷歌开源大模型Gemma(基于Ollama)

参考:本地快速部署谷歌开源大模型Gemma(基于Ollama) - 知乎 确保系统更新: Bash sudo apt update && sudo apt upgrade 需要先下载Ollama,版本要求0.1.26及以上 运行curl -fsSL https://ollama.com/install.sh | sh 监听 Ollama API 接…

常见的限流算法- python版本

shigen坚持更新文章的博客写手,擅长Java、python、vue、shell等编程语言和各种应用程序、脚本的开发。记录成长,分享认知,留住感动。 个人IP:shigen 在系统的稳定性设计中,需要考虑到的就是限流,避免高并发…

【VUe】简略学习 vue

Vue 是一套用于构建用户界面的渐进式框架。要想使用这个框架,就需要先在页面中引用: 如何使用: 来到控制台: 数据绑定 若要在标签里替换,就需要使用 v-bind 指令了: 在标签里(尖括号里&#xf…

数据库insert详细用法

数据库版本:KingbaseES V008R006C008B0014 简介 INSERT 语句用于将数据插入表中,向指定表格添加1行或多行数据,本篇文章主要以kingbase介绍insert的一些技巧。 文章目录如下 1. 基本语法 2. 实用技巧 2.1. 插入其他表数据 2.2. 快速插入万…

【力扣hot100】刷题笔记Day25

前言 这几天搞工作处理数据真是类似我也,还被老板打电话push压力有点大的,还好搞的差不多了,明天再汇报,赶紧偷闲再刷几道题(可恶,被打破连更记录了)这几天刷的是动态规划,由于很成…

HTML5七天学会基础动画网页10(2)

制作立方体 学完前面的基础内容&#xff0c;制作立方体是个不错的练习方法&#xff0c;先看成品 再分析一下&#xff0c;六个面让每个面旋转平移就可以实现一个立方体&#xff0c;来看代码: <title> 制作立方体</title> <style> *{ margin: 0; padding: 0; …

鸿蒙开发:从入门到精通的全方位学习指南

随着华为鸿蒙HarmonyOS生态系统的迅速扩展&#xff0c;越来越多的开发者渴望深入了解并掌握这一前沿技术。本文旨在为鸿蒙开发新手提供一份详尽且实用的学习教程&#xff0c;助您从零开始&#xff0c;逐步迈向鸿蒙开发的巅峰。 一、鸿蒙开发环境搭建 DevEco Studio安装&#x…

C语言--- 指针运算笔试题详解

目录 题目1&#xff1a; 题目2&#xff1a; 题目3&#xff1a; 题目4&#xff1a; 题目5&#xff1a; 题目6&#xff1a; 题目7&#xff1a; 题目1&#xff1a; #include <stdio.h> int main() {int a[5] { 1, 2, 3, 4, 5 };int *ptr (int *)(&a 1);print…

Open3D 利用四个点计算球心和半径 (28)

Open3D 利用四个点计算球心和半径 (28) 一、算法介绍二、算法实现1.代码2.结果一、算法介绍 给定的四个点坐标,计算球心和半径,提供验证的四个点来比较最终的结果是否准确。 二、算法实现 1.代码 代码如下(示例): import numpy as npdef calculate_sphere_center_…

课时61:流程控制_if条件控制_嵌套if实践

2.2.3 嵌套if实践 学习目标 这一节&#xff0c;我们从 基础知识、简单实践、小结 三个方面来学习。 基础知识 简介 一个if语句仅仅能够针对一个场景的多种情况。当我们面对多场景的条件判断的时候&#xff0c;一个if结构语句无法满足需求&#xff0c;这个时候&#xff0c;我…

海格里斯HEGERLS智能托盘四向车系统为物流仓储自动化升级提供新答案

随着实体企业面临需求多样化、订单履行实时化、商业模式加速迭代等挑战&#xff0c;客户对物流仓储解决方案的需求也逐渐趋向于柔性化、智能化。作为近十年来发展起来的新型智能仓储设备&#xff0c;四向车系统正是弥补了先前托盘搬运领域柔性解决方案的空白。随着小车本体设计…