首页 > 编程语言 >python学习笔记(15)算法(8)双向队列

python学习笔记(15)算法(8)双向队列

时间:2024-12-01 18:58:24浏览次数:10  
标签:deque 15 python self 队列 front rear size

在队列中,我们仅能删除头部元素或在尾部添加元素。双向队列(double‑ended queue)提供了更高的灵活性,允许在头部和尾部执行元素的添加或删除操作。

一、双向队列常用操作

  1. 队首入队(push_front):在双向队列的头部添加一个元素。
  2. 队首出队(pop_front):删除双向队列头部的元素。
  3. 队尾入队(push_back):在双向队列的尾部添加一个元素。
  4. 队尾出队(pop_back):删除双向队列尾部的元素。
  5. 访问队首元素(peek_front):获取双向队列头部的元素,但不删除它。
  6. 访问队尾元素(peek_back):获取双向队列尾部的元素,但不删除它。
  7. 获取队列长度(size):返回双向队列中元素的个数。
  8. 判断队列是否为空(isEmpty):如果双向队列为空,则返回true,否则返回false。
from collections import deque
# 初始化双向队列
deque: deque[int] = deque()

# 元素入队
deque.append(2)
# 添加至队尾
deque.append(5)
deque.append(4)
deque.appendleft(3)
# 添加至队首
deque.appendleft(1)
# 访问元素
front: int = deque[0]
# 队首元素
rear: int = deque[-1]
# 队尾元素
# 元素出队
pop_front: int = deque.popleft()
# 队首元素出队
pop_rear: int = deque.pop()
# 队尾元素出队
# 获取双向队列的长度
size: int = len(deque)
# 判断双向队列是否为空
is_empty: bool = len(deque) == 0

二、双向队列实现 *

1.基于双向链表的实现

回顾上一节内容,我们使用普通单向链表来实现队列,因为它可以方便地删除头节点(对应出队操作)和在尾节点后添加新节点(对应入队操作)。
对于双向队列而言,头部和尾部都可以执行入队和出队操作。换句话说,双向队列需要实现另一个对称方向的操作。为此,我们采用“双向链表”作为双向队列的底层数据结构。

将双向链表的头节点和尾节点视为双向队列的队首和队尾,同时实现在两端添加和删除节点的功能。

# 双向链表节点定义
class DListNode:
    def __init__(self, val=0, prev=None, next=None):
        self.val = val
        self.prev = prev
        self.next = next


# 双向队列类定义
class LinkedListDeque:
    def __init__(self):
        self.front = None
        self.rear = None
        self.size = 0

    def push(self, val, is_front=True):
        new_node = DListNode(val)
        if self.size == 0:
            self.front = self.rear = new_node
        elif is_front:
            new_node.next = self.front
            self.front.prev = new_node
            self.front = new_node
        else:
            new_node.prev = self.rear
            self.rear.next = new_node
            self.rear = new_node
        self.size += 1

    def pop(self, is_front=True):
        if self.size == 0:
            raise IndexError("双向队列为空")
        if self.size == 1:
            val = self.front.val
            self.front = self.rear = None
        elif is_front:
            val = self.front.val
            self.front = self.front.next
            self.front.prev = None
        else:
            val = self.rear.val
            self.rear = self.rear.prev
            self.rear.next = None
        self.size -= 1
        return val

    def peek_front(self):
        if self.size == 0:
            raise IndexError("双向队列为空")
        return self.front.val

    def peek_back(self):
        if self.size == 0:
            raise IndexError("双向队列为空")
        return self.rear.val

    def size(self):
        return self.size

    def is_empty(self):
        return self.size == 0


# 示例代码
if __name__ == "__main__":
    deque = LinkedListDeque()
    deque.push(1)
    deque.push(2, is_front=False)
    print(deque.peek_front())
    print(deque.peek_back())
    print(deque.pop())
    print(deque.pop(is_front=False))

2.基于数组的实现

class ArrayDeque:
    def __init__(self, capacity):
        self.capacity = capacity
        self.array = [None] * capacity
        self.front = 0
        self.rear = 0
        self.size = 0

    def is_full(self):
        return self.size == self.capacity

    def is_empty(self):
        return self.size == 0

    def push_front(self, item):
        if self.is_full():
            raise IndexError("队列已满")
        self.front = (self.front - 1 + self.capacity) % self.capacity
        self.array[self.front] = item
        self.size += 1

    def push_back(self, item):
        if self.is_full():
            raise IndexError("队列已满")
        self.array[self.rear] = item
        self.rear = (self.rear + 1) % self.capacity
        self.size += 1

    def pop_front(self):
        if self.is_empty():
            raise IndexError("队列已空")
        item = self.array[self.front]
        self.front = (self.front + 1) % self.capacity
        self.size -= 1
        return item

    def pop_back(self):
        if self.is_empty():
            raise IndexError("队列已空")
        self.rear = (self.rear - 1 + self.capacity) % self.capacity
        item = self.array[self.rear]
        self.size -= 1
        return item

    def peek_front(self):
        if self.is_empty():
            raise IndexError("队列已空")
        return self.array[self.front]

    def peek_back(self):
        if self.is_empty():
            raise IndexError("队列已空")
        return self.array[self.rear - 1 + self.capacity] % self.capacity

    def get_size(self):
        return self.size

标签:deque,15,python,self,队列,front,rear,size
From: https://blog.csdn.net/m0_74370400/article/details/144093997

相关文章

  • python学习笔记(12)算法(5)迭代与递归
    一、迭代迭代(iteration)是一种重复执行某个任务的控制结构。在迭代中,程序会在满足一定的条件下重复执行某段代码,直到这个条件不再满足。迭代通常用于解决需要逐步推进的计算问题,例如遍历数组、计算阶乘等。迭代的优点是内存使用效率高,易于优化,适合处理大规模数据。1.for循环......
  • L2-015 互评成绩
    目录一、问题描述二、问题分析 三、源码解答四、时空复杂度分析五、参考资料一、问题描述学生互评作业的简单规则是这样定的:每个人的作业会被k个同学评审,得到k个成绩。系统需要去掉一个最高分和一个最低分,将剩下的分数取平均,就得到这个学生的最后成绩。本题就要求你编......
  • (2024最新毕设合集)基于python的医疗用品管理平台-35382|可做计算机毕业设计JAVA、PHP、
    摘要本论文主要论述了如何基于Python开发一个医疗用品管理平台,本系统将严格按照软件开发流程进行各个阶段的工作,面向对象编程思想进行项目开发。在引言中,作者将论述医疗用品管理平台的当前背景以及系统开发的目的,后续章节将严格按照软件开发流程,对系统进行各个阶段分析设计。......
  • # 26_Python基础到实战一飞冲天(二)-python基础(二十六)--缺省多值参数和递归
    26_Python基础到实战一飞冲天(二)-python基础(二十六)–缺省多值参数和递归一、缺省参数-02-指定函数缺省参数的默认值1、指定函数的缺省参数在参数后使用赋值语句,可以指定参数的缺省值。2、指定函数的缺省参数定义示例代码(dzs_14_函数的缺省参数定义.py)#dzs_14_函数的......
  • # 25_Python基础到实战一飞冲天(二)-python基础(二十五)--函数返回值和参数
    25_Python基础到实战一飞冲天(二)-python基础(二十五)–函数返回值和参数一、全局变量-06-全局变量定义的位置及代码结构1、python全局变量定义的位置为了保证所有的函数都能够正确使用到全局变量,应该将全局变量定义在其他函数的上方。2、python全局变量定义的位置示例代......
  • 数据结构第一弹-队列
    大家好,今天和大家一起分享一下数据结构中的队列相关内容~队列是一种非常重要的线性数据结构,遵循先进先出(FIFO,FirstInFirstOut)的原则。一、队列概述队列是一种特殊的线性表,它只允许在一端进行插入操作,在另一端进行删除操作。队列的入口称为队尾(rear),出口称为队头(front)。......
  • python毕设社区疫情防控物资调配平台ldly9.程序+论文
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景新冠疫情的爆发使得全球公共卫生体系面临前所未有的挑战,社区作为疫情防控的前沿阵地,其物资调配能力直接关系到疫情防控的成效。在疫情初期......
  • python毕设社区志愿者服务管理系统ic6n8.程序+论文
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着社会的快速发展和居民生活水平的提高,社区志愿者服务在促进社会和谐、提升居民生活质量方面发挥着越来越重要的作用。然而,传统的志愿者......
  • Python中的GIL(全局解释器锁)是什么?它如何影响多线程编程?
    Python中的GIL(全局解释器锁)是什么?它如何影响多线程编程?Python中的GIL(全局解释器锁)是什么?它如何影响多线程编程?摘要引言什么是GIL?为什么它会影响多线程?1.**什么是GIL(全局解释器锁)?**1.1**GIL的目的**1.2**GIL的工作机制**2.**GIL对多线程编程的影响**2.1**多线程不......
  • Python 潮流周刊#79:Python 的元数据困境(摘要)
    本周刊由Python猫出品,精心筛选国内外的250+信息源,为你挑选最值得分享的文章、教程、开源项目、软件工具、播客和视频、热门话题等内容。愿景:帮助所有读者精进Python技术,并增长职业和副业的收入。分享了12篇文章,12个开源项目,2则热门讨论,全文2200字。以下是本期摘要:......