Python数据结构与算法的双端队列详解

目录
  • 什么是双端队列​
  • ​用Python实现双端队列
  • 运用双端队列构建回文检测器
  • 总结

什么是双端队列​

双端队列是与队列类似的有序集合。它有一、一两端,元素在其中保持自己的位置。与队列不同的是,双端队列对在哪一端添加和移除元素没有任何限制。新元素既可以被添加到前端,也可以被添加到后端。同理,已有的元素也能从任意一端移除。某种意义上,双端队列可以是栈和队列的结合。

值得注意的是,尽管双端队列有栈和队列的很多特性,但是它并不要求按照这两种数据结构分别规定的LIFO原则和FIFO原则操作元素。具体的排序原则取决于其使用者。

​双端队列抽象数据类型由下面的结构和操作定义。如前所述,双端队列是元素的有序集合,其任何一端都允许添加或移除元素。双端队列支持以下操作:

  • 创建一个空的双端队列。它不需要参数,且会返回一个空的双端队列。 Deque()
  • 将一个元素添加到双端队列的前端。它接受一个元素作为参数,没有返回值。 addFront(item)
  • 将一个元素添加到双端队列的后端。它接受一个元素作为参数,没有返回值。 addRear(item)
  • 从双端队列的前端移除一个元素。它不需要参数,且会返回一个元素,并修改双端队列的内容。 removeFront()
  • 从双端队列的后端移除一个元素。它不需要参数,且会返回一个元素, 并修改双端队列的内容。 removeRear()
  • 检查双端队列是否为空。它不需要参数,且会返回一个布尔值。 isEmpty()
  • 返回双端队列中元素的数目。它不需要参数,且会返回一个整数。 size()

​用Python实现双端队列

我们通过创建一个新类来实现双端队列抽象数据类型。Python列表再一次提供了 很多简便的方法来帮助我们构建双端队列。在下面的代码中,我们假设双端队列的后端是列表的位置0处(列表的最左端)。

class Deque:
    def __init__(self):
        self.items = []
    def isEmpty(self):
        return self.items == []
    # 往双端队列前端添加元素
    def addFront(self, item):
        self.items.append(item)
    # 往双端队列后端添加元素
    def addRear(self, item):
        self.items.insert(0, item)
    # 在前端移除双端队列元素
    def removeFront(self):
        return self.items.pop()
    # 在后端移除双端队列元素
    def removeRear(self):
        return self.items.pop(0)
    def size(self):
        return len(self.items)
    def look(self):
        print(self.items)

removeFront 使用 pop 方法移除列表中的最后一个元素,removeRear 则使用 pop(0) 方法移除列表中的第一个元素。同理,之所以 addRear 使用 insert 方法,是因为 append 方法只能在列表的最后(最右端)添加元素。​

代码运行效果如下:

运用双端队列构建回文检测器

我们现在运用双端队列解决一个非常有趣的经典问题:回文问题。回文是指从前往后读和从后往前读都一样的字符串,例如 sos、radar、toot、madam 等等。我们将构建一个程序,它接受一个字符串并且检测其是否为回文。​

该问题的解决方案是使用一个双端队列来存储字符串中的字符。按照从左往右的顺序将字符串中的字符添加到双端队列的后端或前端。此时,该双端队列类似于一个普通的队列。​

由于可以从前后两端移除元素,因此我们能够比较两个元素,并且只有在二者相等时才继续。如果一直匹配第一个和最后一个元素,最终会处理完所有的字符(如果字符数是偶数),或者剩下只有一个元素的双端队列(如果字符数是奇数)。任意一种结果都表明输入字符串是回文。​

回文检测器代码如下:

class Deque:
    def __init__(self):
        self.items = []
    def isEmpty(self):
        return self.items == []
    def addFront(self, item):
        self.items.append(item)
    def addRear(self, item):
        self.items.insert(0, item)
    def removeFront(self):
        return self.items.pop()
    def removeRear(self):
        return self.items.pop(0)
    def size(self):
        return len(self.items)

def palchecker(aString):
    chardeque = Deque()
    for ch in aString:
        chardeque.addFront(ch)
    stillEqual = True
    while chardeque.size() > 1 and stillEqual:
        first = chardeque.removeFront()
        last = chardeque.removeRear()
        if first != last:
            stillEqual = False
    return stillEqual

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • 详解Python的collections模块中的deque双端队列结构

    deque 是 double-ended queue的缩写,类似于 list,不过提供了在两端插入和删除的操作. appendleft 在列表左侧插入 popleft 弹出列表左侧的值 extendleft 在左侧扩展 例如: queue = deque() # append values to wait for processing queue.appendleft("first") queue.appendleft("second") queue.appendl

  • python数据结构之栈、队列及双端队列

    目录 1.线性数据结构的定义 2.栈 2.1 栈的定义 2.2 栈的数据类型 2.3 用python实现栈 2.4 栈的应用 3. 队列 3.1 队列的定义 3.2 队列抽象数据类型 3.3 用python实现队列 3.3 队列的应用 4. 双端队列 4.1 双端队列的定义 4.2 双端队列抽象数据类型 4.3 用python实现双端队列 4.3 双端队列的应用 5.链表 5.1 链表定义 5.2 用python实现链表 前文学习: python数据类型: python数据结构:数据类型. py

  • Python实现的数据结构与算法之双端队列详解

    本文实例讲述了Python实现的数据结构与算法之双端队列.分享给大家供大家参考.具体分析如下: 一.概述 双端队列(deque,全名double-ended queue)是一种具有队列和栈性质的线性数据结构.双端队列也拥有两端:队首(front).队尾(rear),但与队列不同的是,插入操作在两端(队首和队尾)都可以进行,删除操作也一样. 二.ADT 双端队列ADT(抽象数据类型)一般提供以下接口: ① Deque() 创建双端队列 ② addFront(item) 向队首插入项 ③ addRe

  • python双端队列原理、实现与使用方法分析

    本文实例讲述了python双端队列原理.实现与使用方法.分享给大家供大家参考,具体如下: 双端队列 双端队列(deque,全名double-ended queue),是一种具有队列和栈的性质的数据结构. 双端队列中的元素可以从两端弹出,其限定插入和删除操作在表的两端进行.双端队列可以在队列任意一端入队和出队. 操作 Deque() 创建一个空的双端队列 add_front(item) 从队头加入一个item元素 add_rear(item) 从队尾加入一个item元素 remove_front(

  • Python双端队列deque的实现

    目录 前言 基本用法 填充 线程安全 旋转 限制双端队列大小 前言 双端队列deque支持从任意一端增加和删除元素.其中,栈和队列就是双端队列的退化形式,它们的输入输出被限制在某一端. 基本用法 首先,我们来看看容器collections.deque()函数的基本用法.具体代码如下所示: import collections c = collections.deque('abcdefg') print("输出双端队列:", c) print("双端队列的长度:",

  • Python双端队列实现回文检测

    目录 一.双端队列 二.回文检测 补充 一.双端队列 双端队列 Deque 是一种有次序的数据集,跟队列相似,其两端可以称作"首" 和 "尾"端,但 Deque 中数据项既可以从队首加入,也可以从队尾加入:数据项也可以从两端移除.某种意义上说,双端队列集成了栈和队列的能力. 但双端队列并不具有内在的 LIFO 或者 FIFO 特性,如果用双端队列来模拟栈或队列,需要由使用者自行维护操作的一致性. 用 Python 实现抽象数据类型Deque,Deque定义的操作如下

  • Python数据结构与算法的双端队列详解

    目录 什么是双端队列​ ​用Python实现双端队列 运用双端队列构建回文检测器 总结 什么是双端队列​ 双端队列是与队列类似的有序集合.它有一前.一后两端,元素在其中保持自己的位置.与队列不同的是,双端队列对在哪一端添加和移除元素没有任何限制.新元素既可以被添加到前端,也可以被添加到后端.同理,已有的元素也能从任意一端移除.某种意义上,双端队列可以是栈和队列的结合. 值得注意的是,尽管双端队列有栈和队列的很多特性,但是它并不要求按照这两种数据结构分别规定的LIFO原则和FIFO原则操作元素.具

  • Python数据结构与算法之链表,无序链表详解

    目录 我们首先来构造节点. 节点(Node)的类构建完毕后,接下来我们开始构建整个链表(LinkList)的类. 那么我们还需要一个方法来判断链表头的指向. 接下来我们构建链表节点的添加方法. 实现length方法(计算链表中节点的个数/链表长度) 实现search方法(搜索链表中的某个节点) 实现remove方法(移除链表中的某个节点) 代码汇总 总结 链表是一系列元素的集合,这些元素的内存是散乱的. 无序链表则是一系列逻辑无序元素的集合,只是通过链表数据结构连接起来.虽然这些元素整体来看是散

  • C++数据结构与算法之双缓存队列实现方法详解

    本文实例讲述了C++数据结构与算法之双缓存队列实现方法.分享给大家供大家参考,具体如下: "双缓存队列"是我在一次开发任务中针对特殊场景设计出来的结构.使用场景为:发送端持续向接收端发送数据包--并且不理会接收端是否完成业务逻辑.由于接收端在任何情况下停止响应即可能产生数据丢失,因此无法简单的设计一条线程安全队列来对数据写入或读取(读取数据时将队列上锁视为对写入的停止响应). 鉴于此,我的设计思路如下: 接收端首先向A队列中写入数据,然后当数据处理请求到来的时候切换到B队列继续写入,之

  • Java超详细精讲数据结构之bfs与双端队列

    目录 一.bfs 二.双端队列 三.算法题 1.kotori和迷宫 2.小红找红点 3.小红玩数组 一.bfs bfs(广度优先搜索),类似二叉树的层序遍历,利用队列完成.一般用于求最短路. 图的最短路问题: 给定一个无向图,每条边的长度都是1.求1号点到x号点的最短距离. 顶点数n 边数为m q次询问 输入x 输出1到x的最短距离. 若1号点到x不连通,则输出-1 二.双端队列 双端队列的应用(区间翻转): 对于长度为n的数组,给定一个长度为m的区间,区间初始位置为a[1]到a[m]. 3种操

  • 详解C++图搜索算法之双端队列广搜

    目录 广度优先遍历 双端队列BFS 例题:AcWing 175. 电路维修 解题思路 AC代码 广度优先遍历 广度优先遍历是一种按照层次顺序进行访问的方法,它具有以下两种重要性质: 在访问完所有第i层的结点后,才会去访问第i+1层的结点 任意时刻,队列中至多有两个层次的结点.若其中一部分结点属于第i层,则另一部分结点属于第i+1层,并且所有第i层结点排在第i+1层之前.也就是说,广度优先遍历队列中的元素关于层次满足 双端队列BFS 在最基本的广度优先搜索中,每次沿着分支的扩展都记为“一步”,我们

  • 数据结构与算法中二叉树子结构的详解

    数据结构与算法中二叉树子结构的详解 需求 输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构) 树的描述: class TreeNode { int val = 0; TreeNode left = null; TreeNode right = null; public TreeNode(int val) { this.val = val; } } 解决思路 使用了栈将元素入栈,并不断的弹出元素,弹出一个元素的时候,拼接成字符串,并用特殊符号进行区分,该方法

  • Python算法应用实战之队列详解

    队列(queue) 队列是先进先出(FIFO, First-In-First-Out)的线性表,在具体应用中通常用链表或者数组来实现,队列只允许在后端(称为rear)进行插入操作,在前端(称为front)进行删除操作,队列的操作方式和堆栈类似,唯一的区别在于队列只允许新数据在后端进行添加(摘录维基百科). 如图所示 队列的接口 一个队列至少需要如下接口: 接口 描述 add(x) 入队 delete() 出队 clear() 清空队列 isEmpty() 判断队列是否为空 isFull() 判断

  • python数据结构之图深度优先和广度优先实例详解

    本文实例讲述了python数据结构之图深度优先和广度优先用法.分享给大家供大家参考.具体如下: 首先有一个概念:回溯 回溯法(探索与回溯法)是一种选优搜索法,按选优条件向前搜索,以达到目标.但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为"回溯点". 深度优先算法: (1)访问初始顶点v并标记顶点v已访问. (2)查找顶点v的第一个邻接顶点w. (3)若顶点v的邻接顶点w存在,则继续执行:否则回

  • java数据结构排序算法之树形选择排序详解

    本文实例讲述了java数据结构排序算法之树形选择排序.分享给大家供大家参考,具体如下: 这里我们就来说说选择类排序之一的排序:树形选择排序 在简单选择排序中,每次的比较都没有用到上次比较的结果,所以比较操作的时间复杂度是O(N^2),想要降低比较的次数,则需要把比较过程中的大小关系保存下来.树形选择排序是对简单选择排序的改进. 树形选择排序:又称锦标赛排序(Tournament Sort),是一种按照锦标赛的思想进行选择排序的方法.首先对n个记录的关键字进行两两比较,然后在n/2个较小者之间再进

随机推荐