队列的实现方式—Python数据结构(三)

news2024/11/27 8:34:46

队列

1. 定义

队列是一种常见的数据结构,用于按照先进先出(FIFO)的原则管理数据项。在Python中,有多种方法可以实现队列,其中最常见的包括使用列表(list)和使用标准库中的 queue 模块。队列通常用于解决需要按照特定顺序处理数据项的问题,例如任务调度、数据缓冲、事件处理等。
队列是限制在两端进行插入和删除操作操作的线性表,允许进行存入操作的一端称为“队尾”,允许进行删除操作的一端称为“队头”。
队列类似于一条管道,需要注意的是:队列都是在内存中操作,进程退出,队列清空,另外,队列也是一个阻塞的形态。

2. 特点

  • 队列只能在队头和队尾进行数据操作

  • 队列模型具有先进先出或者叫做后进后出的规律。

队列

3. 队列的代码实现

队列的操作有入队,出队判断队列的空满等操作。

  • 使用列表(顺序存储)实现队列:squeue.py
  • 链式存储代码实现队列:lqueue.py
  • 使用 queue实现队列:queuetest.py
  • 使用 deque实现队列:dequetest.py

3.1 列表实现队列(顺序存储)

squeue.py

# @Author : Kql
# @Time : 2023/10/17 14:54
"""
squeue队列的顺序存储
思路分析:
1. 基于列表完成数据存储。
2. 通过封装规定数据操作。
"""


# 自定义异常类
class QueueError(Exception):
    pass


# 队列操作
class SQueue:
    def __init__(self):
        self._elems = []

    # 判定队列为空
    def is_empty(self):
        return self._elems == []

    # 入队,列表的尾部定义为队尾
    def enqueue(self, val):
        self._elems.append(val)

    # 出队,列表的第一个元素
    def dequeue(self):
        if not self._elems:
            raise QueueError("Queue is empty")
        return self._elems.pop(0)


from sstack import *


# 如何将出队的数据进行翻转,即先出队入栈,之后在出栈入队
def convert_queue():
    sqe = SQueue()
    for i in range(10):
        sqe.enqueue(i)

    st = SStack()
    # 出队入栈
    while not sqe.is_empty():
        st.push(sqe.dequeue())
    # 出栈入队
    while not st.is_empty():
        sqe.enqueue(st.pop())
    # 直接出队
    while not sqe.is_empty():
        print(sqe.dequeue())


if __name__ == '__main__':
	# 如何将出队的数据进行翻转,即先出队入栈,之后在出栈入队
    convert_queue()
    #正常的队列顺序存储
    sq = SQueue()
    sq.enqueue(10)
    sq.enqueue(20)
    sq.enqueue(30)
    while not sq.is_empty():
         print(sq.dequeue())

3.2 链式存储代码实现队列

lqueue.py

# @Author : Kql
# @Time : 2023/10/17 16:05
"""
lqueue.py 链式队列
思路分析:
1. 基于链表构建队列模型
2. 链表的开端作为队头,结尾位置作为队尾。
3. 单独定义队尾标记,避免每次插入数据遍历。
4. 队头和队尾重叠时认为队列为空。
"""


# 自定义异常类
class QueueError(Exception):
    pass


# 节点类
class Node:
    def __init__(self, val, next=None):
        self.val = val
        self.next = next


class LQueue:
    def __init__(self):
        # 定义队头和队尾的属性变量
        self.front = self.rear = Node(None)

    # 判定队列为空
    def is_empty(self):
        return self.front == self.rear

    # 入队
    def enqueue(self, val):
        self.rear.next = Node(val)
        self.rear = self.rear.next

    # 队列出队
    def dequeue(self):
        if self.front == self.rear:
            raise QueueError("Queue is empty")
        # 此时front节点已经将第一个节点出队了,只是明面上指向一个地址节点。
        self.front = self.front.next
        return self.front.val


if __name__ == '__main__':
    sq = LQueue()
    sq.enqueue(10)
    sq.enqueue(20)
    sq.enqueue(30)
    while sq.is_empty():
        print(sq.dequeue())

3.3 使用 queue实现队列

queuetest.py

import queue

# 创建一个队列
q=queue.Queue(5)    #如果不设置长度,默认为无限长
print(q.maxsize)    #注意没有括号

# 添加元素到队列
q.put(1)
q.put(2)
q.put(3)

# 从队列中取出元素
item = q.get()
print(item)  
# 输出: 1

3.4 使用 deque实现队列

Deque 类实现了一个双端队列(double-ended queue),支持从队列两端添加和取出元素。
dequetest.py

from collections import deque
#创建一个 deque 对象:
my_deque = deque()

#在队列头部添加元素:使用 appendleft() 方法。
my_deque.appendleft(1)
my_deque.appendleft(2)

#在队列尾部添加元素:使用 append() 方法。
my_deque.append(3)
my_deque.append(4)

#从队列头部取出元素:使用 popleft() 方法。
item = my_deque.popleft()  # 取出并移除队列头部的元素
print(item)  # 输出: 2

#从队列尾部取出元素:使用 pop() 方法。
item = my_deque.pop()  # 取出并移除队列尾部的元素
print(item)  # 输出: 4

使用 deque 类可以使队列的两端操作非常高效,因为它是双向链表的实现,允许在常数时间内进行这些操作。这对于需要频繁从队列两端添加和删除元素的问题非常有用,如广度优先搜索、循环缓冲区等。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

docker运行nginx镜像

今天在这里讲如何在docker上运行nignx镜像,并将配置文件和目录挂载到宿主机上,以实现方便统一的管理配置信息。 首先第一步需要拉取镜像,我们还是拉取最新的镜像,不需要添加tag版本号, docker pull nginx 拉取结束后用…

反射的作用( 越过泛型检查 和 可以使用反射保存所有对象的具体信息 )

1、绕过 编译阶段 为集合添加数据 反射是作用在运行时的技术,此时集合的泛型将不能产生约束了,此时是可以 为集合存入其他任意类型的元素的 。泛型只是在编译阶段可以约束集合只能操作某种数据类型,在 编译成Class文件进入 运行阶段 的时候&a…

Zebec Protocol 薪酬支付工具 WageLink 上线,掀新一轮薪酬支付浪潮

Zebec Protocol 正在从多个方面推动流支付的应用,除了作为一种全新的支付手段来对支付领域进行重塑外,其也在以流支付体系为基础,不断地向薪酬发放领域深度的拓展。 在今年早些时候,Zebec Protocol 通过美国投资机构 Payroll Grow…

【类和对象+this引用】

文章目录 面向对象与面向过程面向对象关注的是对象,用类描述这个对象如何定义类如何更改类名 类的实例化this引用总结 面向对象与面向过程 面向对象就是解决问题的一种思想,主要依靠对象之间的交互完成一件事情。 面向过程好比传统的洗衣服方式&#x…

【RNA world】RNA的多功能性与早期生命进化

文章目录 RNARNA plays core functions in Central Dogma of BiologyrRNAsnRNA RNA worldReplication催化作用感知环境变化并作出响应 来自Manolis Kellis教授(MIT计算生物学主任)的课 油管链接:6.047/6.878 Lecture 7 - RNA folding, RNA wo…

[尚硅谷React笔记]——第5章 React 路由

目录: 对SPA应用的理解对路由的理解前端路由原理路由的基本使用路由组件与一般组件NavLink的使用封装NavLink组件Switch的使用解决样式丢失问题路由的模糊匹配与严格匹配Redirect的使用嵌套路由向路由组件传递params参数向路由组件传递search参数.向路由组件传递st…

【Docker从入门到入土 3】Docker镜像的创建方法

Part3 一、Docker镜像1.1 镜像的概念1.2 镜像结构的分层 二、Docker镜像的创建2.1 基于现有镜像创建2.1.1 创建思路2.1.2 举个例子 2.2 基于本地模板创建2.3 基于Dockerfile 创建 三、Dockerfile 详解3.1 Dockerfile 操作指令3.1.1 常用的操作指令3.1.2 CMD和ENTRYPOINT的区别…

【Java基础面试四十一】、说一说你对static关键字的理解

文章底部有个人公众号:热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享? 踩过的坑没必要让别人在再踩,自己复盘也能加深记忆。利己利人、所谓双赢。 面试官:说一说你对static关键字…

hdlbits系列verilog解答(异或非门)-08

文章目录 wire线网类型介绍一、问题描述二、verilog源码三、仿真结果 wire线网类型介绍 wire线网类型是verilog的一种数据类型,它是一种单向的物理连线。它可以是输入也可以是输出,它与reg寄存器数据类型不同,它不能存储数据,只能…

文件系统相关

文件系统部分的大纲要求: 文件系统的全局结构:文件系统在外存中的结构,文件系统在内存中的结构外存空闲空间管理办法虚拟文件系统文件系统挂载 一、文件系统的层次结构 可分为三个层次:最低层是对象及其属性,中间层…

物证管理系统|智物证DW-S404是一套成熟系统

系统背景 我司物证智能管理系统(智物证DW-S404)是一套成熟系统,依托互3D技术、RFID技术、数据库技术、AI、视频分析技术对物证进行统一管理、分析的信息化、智能化、规范化的系统。 物证是公安或者监狱处理案件的关键凭证,针对过…

3交换机的配置与使用

越来越发觉大学的教程是真好,虽然说深度可能不太够,但作为入门实在太好了。中国也有公开课,推荐中国大学MOOC,感谢网易有道与高教社。 最近特别累、活也特别多,所以学习的时间少了很多。但看到MOOC之后,又…

软件测试(六)自动化测试 Junit5

Junit5 selenium是自动化测试框架(写自动化测试用例)Junit单元测试框架(管理写好的测试用例) 注解:Test,Disable ,BeforeAll,AfterAll,BeforeEach,AfteEach…

操作系统——多个类别产品的生产者-消费者问题(王道视频p33、课本ch6)

1.问题解剖——得到的是 1个“互斥信号量” 3个“同步信号量” 其中特别注意,对于盘子plate可以清空的设计4个对象的,但是只用这一个同步信号量就可以实现 2.代码—— 3.由于这里的同步信号量的初值都是1,所以,即使不设置互斥信…

04.Finetune vs. Prompt

目录 语言模型回顾大模型的两种路线专才通才二者的比较 专才养成记通才养成记Instruction LearningIn-context Learning 自动Prompt 部分截图来自原课程视频《2023李宏毅最新生成式AI教程》,B站自行搜索 语言模型回顾 GPT:文字接龙 How are __. Bert&a…

大语言模型(LLM)综述(二):开发大语言模型的公开可用资源

A Survey of Large Language Models 前言3. RESOURCES OF LLMS3.1 公开可用的模型CheckPoints或 API3.2 常用语料库3.3 库资源 前言 随着人工智能和机器学习领域的迅速发展,语言模型已经从简单的词袋模型(Bag-of-Words)和N-gram模型演变为更…

RK3568 USB驱动开发

一.USB的DTS配置说明 1.USB 2.0 控制器 DTS 1.1 USB 2.0 Host 控制器 DTS USB 2.0 Host0 控制器 (EHCI & OHCI) 的DTS为例: 其中,EHCI 控制器的 compatible 固定为 “generic-ehci”,OHCI 控制器的 compatible 固定为 “genericohci”…

39.克鲁斯卡尔(Kruskal)算法

一言 已知n个顶点,选n-1条最短的边,不可成环。 概述 克鲁斯卡尔(Kruskal)算法是用来求加权连通图的最小生成树的算法。其基本思想是按照权值从小到大的顺序选择n-1条边,保证这n-1条边不构成回路。 这就要求要首先构…

写给Java/Android开发者的Python入门教程

1. 前言 对于Java/Android开发工程师来说,已经掌握了Java语言,这时再学其他语言(C/C除外),都是比较容易的,可能花上几个小时就能入门了。 作为一个Android开发工程师,今天一时兴起,学了下Python&#xff0…