栈和队列——python

article/2025/11/7 11:16:19

目录

一、栈

定义一个栈

栈的应用——括号匹配问题

栈的应用——迷宫问题

二、队列

自定义队列

python队列的内置模块

队列应用——打印文件后五行

队列应用——迷宫问题


python的数据结构与算法之栈与队列

自学视频:bilibili路飞学城清华大学博士讲解Python数据结构与算法

一、栈

定义一个栈

class Stack:def __init__(self):self.stack = []def push(self, element):self.stack.append(element)def pop(self):return self.stack.pop()def get_top(self):if len(self.stack) > 0:return self.stack[-1]   # 取栈顶元素即列表最后一个元素else:return Nonedef is_empty(self):return len(self.stack) == 0def stack_all(self):return self.stack

栈的规则:先进后出First in Last out

栈的应用——括号匹配问题

def brace_match(s):match = {'}': "{", "]": "[", ")": "("}stack = Stack()for ch in s:if ch in {"(", "{", "["}:stack.push(ch)else:if stack.is_empty():return Falseelif stack.get_top() == match[ch]:stack.pop()else:return Falseif stack.is_empty():return Trueelse:return False

测试:

栈的应用——迷宫问题

# 定义迷宫,1表示墙,不能走,0表示路,能走
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],
]
# 表示4个方向: 上(x-1,y),右(x,y+1),下(x+1,y),左(x,y-1)
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 = []
# 深度优先搜索思想,一条道走到黑,最后的路径不一定是最短的
def maze_path(x1, y1, x2, y2):""":param x1: 起点纵坐标:param y1: 起点横坐标:param x2: 终点纵坐标:param y2: 终点横坐标:return:"""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)    # 将nextNode入栈maze[nextNode[0]][nextNode[1]] = 2   # 将该点标记为走过break# 如果一个方向都不能走,就回退else:stack.pop()     # 栈顶出栈else:print("没有路")return False

测试:

maze_path(1, 1, 8, 8)

二、队列

自定义队列

class Queue:def __init__(self, size=100):self.size = sizeself.queue = [0 for _ in range(self.size)]self.rear = 0  # 队尾指针self.front = 0  # 队首指针def push(self, element):if not self.is_filled():self.rear = (self.rear+1) % self.sizeself.queue[self.rear] = elementelse:raise IndexError("Queue is filled.")def pop(self):if not self.is_empty():self.front = (self.front + 1) % self.sizereturn self.queue[self.front]else:raise IndexError("Queue in empty.")# 判断队空def is_empty(self):return self.rear == self.front# 判断队满def is_filled(self):return (self.rear + 1) % self.size == self.front# 测试
q = Queue(5)
for i in range(4):q.push(i)
print(q.is_filled())

python队列的内置模块

from collections import deque# 单向队列
q = deque()
q2 = deque([1, 2, 3], 5)   # 第一个参数为初始进队元素,第二个元素设置队列最大长度
# 队满之后再进队时,队首元素会自动出队
# 对尾进队
q.append(1)
# 队首出队
print(q.popleft())# 双向队列
q.appendleft(1)  # 队首进队
q.pop()  # 队尾出队

队列应用——打印文件后五行

创建一个文本文件,随便输入几行

from collections import deque
# 使用队列打印文件后五行
with open('test.txt', 'r') as f:q = deque(f, 5)# print(q)for line in q:print(line, end="")

结果:

队列应用——迷宫问题

变量定义:
 

from collections import deque# 定义迷宫,1表示墙,不能走,0表示路,能走
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],
]
# 表示4个方向: 上(x-1,y),右(x,y+1),下(x+1,y),左(x,y-1)
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),
]

 封装方法:

# 走出迷宫后打印路径
def print_path(parent):curNode = parent[-1]  # 此时终点就是parent的最后一个元组min_path = []   # 存放最短路径坐标# 当遍历到起点位置时,即curNode[2]==-1,就终止循环while curNode[2] != -1:min_path.append((curNode[0], curNode[1]))# 下一个结点curNode = parent[curNode[2]]min_path.append(curNode[0:2])   # 最后还要将起点放入min_pathmin_path.reverse()   # 将列表反转,变成从起点到终点表示# 打印输出最短路径:for p in min_path:print(p)
# 广度优先搜索思想,找到的路径就是最短路径
def maze_path_queue(x1, y1, x2, y2):queue = deque()# -1代表当前结点的前一个结点(父结点)queue.append((x1, y1, -1))parent = []   # 用来存放出队的父结点while len(queue) > 0:# 先将当前节点出队并暂时用curNode保存curNode = queue.popleft()parent.append(curNode)if curNode[0] == x2 and curNode[1] == y2:# 到达终点,调用自定义的print_path函数回溯找到这条最优路径print_path(parent)return Truefor dir in dirs:nextNode = dir(curNode[0], curNode[1])# 如果下一个结点为0,表示有路,就把他入队if maze[nextNode[0]][nextNode[1]] == 0:# queue中要存三个元素,下一个结点的坐标以及其父节点在parent列表中的下标# 此时nextNode的父节点就是parent列表的最后一个元素,所以其下标就是len(parent)-1queue.append((nextNode[0], nextNode[1], len(parent)-1))maze[nextNode[0]][nextNode[1]] = 2   # 标记为已经走过# 这里不用break,因为要将所有能走的方向都走完,与深度优先搜索不同else:print("没有路")return False

测试:

 


http://chatgpt.dhexx.cn/article/H7co5M5w.shtml

相关文章

栈和队列的概念

文章目录 栈、队列和双端队列栈队列双端队列Java 中的栈、队列和双端队列 单调栈和单调队列二叉堆和优先队列二叉堆优先队列 目录 栈、队列和双端队列 栈和队列是常见的数据结构。栈的特点是后进先出,添加元素、删除元素和查看元素都在栈顶操作。队列的特点是先进先…

栈和队列详解

文章目录 前言一、栈:1.栈的基本概念:2.如何实现栈?3.栈代码演示: 二、队列:1.队列的基本概念:2.如何实现队列?3.队列代码演示: 总结 前言 栈和队列也属于线性表,但是它…

【数据结构】栈和队列详细分析(全)

目录 1.前言2.栈的定义与特点2.1顺序栈的定义2.2顺序栈的操作2.3链栈的定义2.4链栈的操作 3.队列的定义与特点3.1循环队列3.2循环队列的操作3.3链队的定义3.4链队的操作 4.总结 1.前言 栈和队列是两种重要的线性结构。从数据结构角度看,栈和队列也是线性表&#xf…

【Python数据结构系列】❤️《栈(顺序栈与链栈)》——❤️知识点讲解+代码实现

灵魂拷问:为什么要学数据结构? 数据结构,直白地理解,就是研究数据的存储方式。数据存储只有一个目的,即为了方便后期对数据的再利用。因此,数据在计算机存储空间的存放,决不是胡乱的&#xff0c…

数据结构——栈与队列

目录 一、栈 1.栈的定义 2.栈的分类与基本操作 1. 顺序栈 2.链栈 3.栈与递归的实现 1.递归的简单描述 2.递归过程及与栈的关联 3.递归过程示意图 二.队列 1.队列的定义 2.队列的分类与基本操作 1.顺序队列 2.链队列 3.循环队列 1.假溢出 2.循环队列 3.循环队列相…

栈与队列详解

目录 申明1. 栈的定义1.1 栈的定义1.2 进栈出栈变化形式 2. 栈的抽象数据类型3. 栈的顺序存储结构及实现3.1 栈的顺序存储结构3.2 栈的顺序存储结构——进栈操作3.3 栈的顺序存储结构——出栈操作 4. 两栈共享空间5. 栈的链式存储结构及实现5.1 栈的链式存储结构5.2 栈的链式存…

栈与队列(超详细)

目录 一、栈(Stack)1、什么是栈?2、栈的常见方法3、自己实现一个栈(底层用一个数组实现) 二、队列(Queue)1、什么是队列?2、队列的常见方法3、队列的实现(单链表实现&…

C语言---栈和队列

严格来说,栈和队列都属于线性表 "一对一" 栈:"先进后出" 队列: "先进先出" 栈 栈只能从一端存取,另一端是封闭的 在栈中,不论是存还是取,都必须遵循"先进后出"的原则 >栈是一种只能从表的一端存取数据,且遵循"先进后出…

数据结构与算法——栈和队列

😊数据结构与算法——栈和队列 🚀前言🚀栈(satck)🚢栈的定义🚢共享栈(节省空间)🚢栈的表示和实现(顺序栈)👻顺序栈的定义&…

数据结构:栈和队列(Stack Queue)【详解】

友情链接:数据结构专栏 目录 栈和队列【知识框架】 栈一、栈的基本概念1、栈的定义2、栈的常见基本操作 二、栈的顺序存储结构1、栈的顺序存储2、顺序栈的基本算法(1)初始化(2)判栈空(3)进栈&a…

web 移动端开发基础

web 移动端开发基础 文章目录 web 移动端开发基础了解视口相关内容meta 视口标签掌握二倍图用法物理像素 & 物理像素比多倍图二倍精灵图做法 了解移动端常见选择方案掌握移动端常见问题解决方案移动端常见的布局方式流式布局(百分比布局)flex 布局 -…

Web移动端

1.PC端和移动端的区别: PC端:屏幕大 用网页固定版心,要考虑浏览器兼容问题,(布局:浮动+定位+标准流) 移动端: 手机屏幕小,网页宽度多数为100%,是适配手机屏幕宽度 移动端则基本不需要考虑兼容性问题,放心大胆使用CS…

移动端网页开发基础

文章目录 前言一、浏览器1.pc端常见浏览器2.移动端常见浏览器 二、视口1.布局视口layout viewport2.视觉视口visual viewport3.理想视口ideal viewport 三、二倍图1.物理像素和物理像素比2.二倍图用法 四、移动端开发选择1.单独制作移动端页面2.响应式兼容pc移动端3.移动端常见…

20.【移动端Web开发之响应式布局】

文章目录 【移动端Web开发之响应式布局】前端小抄(20)一、响应式开发1.1 响应式开发原理1.2 响应式布局容器 二、Bootstrap前端开发框架2.1 Bootstrap简介2.2 Bootstrap使用2.3 布局容器 三、Bootstrap栅格系统3.1 栅格系统简介3.2 栅格选项参数3.3 列嵌套3.4 列偏移3.5 列排序…

H5移动web开发

目录 1、H5 的新特性有哪些?C3 的新特性有哪些? 2、如何使一个盒子水平垂直居中? 方法一:利用定位(常用方法,推荐) 方法二:利用 margin:auto 方法三:利用 display:table-cell 方法四…

手摸手带你学移动端WEB开发

HTML常用标签总结手摸手带你学CSSHTML5与CSS3知识点总结 好好学习,天天向上 本文已收录至我的Github仓库DayDayUP:github.com/RobodLee/DayDayUP,欢迎Star ⭐⭐⭐⭐⭐转载请注明出处!⭐⭐⭐⭐⭐ 链接:https://blog.c…

移动端网页开发(一)

一、项目代码初始化 1.打开index.html将<meta></meta>标签补充完整 <html><head><meta charset"utf-8"><meta name"viewport" content"widthdevice-width,initial-scale1.0&#xff0c;minimum-scale1.0,maximum-…

web移动开发

web移动开发 手机内置浏览器&#xff1a; Android&#xff1a;Andriod BrowserIOS&#xff1a;Mobile SafariBlackBerry&#xff1a;WebkitSymbian S60&#xff1a; Web Browser for S60 其浏览器的核心都是基于Webkit 智能手机Web浏览器的特点: 有限的屏幕尺寸触屏、缩放硬…

移动端页面开发

移动端页面开发需要掌握的…… 移动端开发指的是&#xff1a;需要适配移动设备的网页开发移动开发与pc端开发没有本质的区别&#xff0c;使用的也还是HTML/CSS/JS的技术 一、移动端与pc端开发的区别在于&#xff1a; 1.浏览器不同 手机浏览器是webkit的天下&#xff0c;就目…

从零开始学习移动端Web开发

背景 近年来&#xff0c;随着智能手机的普及&#xff0c;移动端开发受到了异常的关注。从传统的安卓、IOS原生手机系统应用开发&#xff0c;转向了移动端Web开发或者是混合开发&#xff0c;既然有需求&#xff0c;那就让我们一起来学习移动端Web开发吧。本文旨在让读者以最快的…