Python之双向队列 (deque)

本文介绍双向队列的概念及操作,包括创建、增删元素等,并通过一个编程实例展示如何生成一个‘震荡’队列,即元素按特定规律交错分布的队列。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


任务描述

本关任务:编写一个能输出“震荡”队列的程序。

双向队列 (deque)

双向队列是一种能在队列两端都进行入队出队操作的数据结构,比普通的队列更加灵活也更加复杂。

创建双向队列

就像计数器Counter,双向队列可以调用无参构造函数创建一个空队列,也可以使用可迭代对象创建并初始化一个队列,比如:

  1. d = collections.deque() #创建一个空队列
  2. d = collections.deque(['a','b','c']) #从list创建
  3. d = collections.deque(('a','b','c')) #从tuple创建
  4. d = collections.deque({'a':0,'b':1,'c':2}) #从dict创建
  5. d = collections.deque("abc") #从字符串创建

第一行语句创建一个空队列,下面四行语句创建了含有元素abc的队列,要注意当从dict创建时,使用的是它的键key,而不是值value

队列操作

双向队列与list类似,也有appendpop这两个成员函数,他们的作用分别是向队列的右边增加元素和从队列的右边删除并返回一个元素,比如:

  1. d.append('d') #向右边增加一个元素'd'
  2. print(d)
  3. d.pop() #从右边删除一个元素
  4. print(d)

得到的结果:
deque(['a', 'b', 'c', 'd'])
deque(['a', 'b', 'c'])

appendpop相对应的,还有一组对队列左边进行操作的函数:appendleftpopleft,用法也与前面的一组类似:

  1. d.appendleft('+') #向左边增加一个元素'd'
  2. print(d)
  3. d.popleft() #从左边删除一个元素
  4. print(d)

得到的结果:
deque(['+', 'a', 'b', 'c'])
deque(['a', 'b', 'c'])

双向队列还提供了一对操作:extendextendleft,用于将一个可迭代对象的所有迭代值依次加入到队列的右边或者左边:

  1. d1 = collections.deque()
  2. d1.extend("123")
  3. print(d1)
  4.  
  5. d1 = collections.deque()
  6. d1.extendleft("123")
  7. print(d1)

得到的结果是:
deque(['1', '2', '3'])
deque(['3', '2', '1'])
可以注意到上下两个结果的值的顺序是相反的

编程要求

根据提示,补充右侧编辑器代码完成函数功能,函数读取输入的一个数字n(n≥0),然后输出一个有n个元素,元素从0n-1“震荡”的队列,“震荡”的定义见测试说明。

测试说明

当输入:3时,输出的“震荡”队列应该是:
deque([1, 0, 2])

当输入:5时,输出的“震荡”队列应该是:
deque([3, 1, 0, 2, 4])

import collections
def Func():
    #在此处填充代码实现功能
    n = int(input())
    if (n>=0):
        d = collections.deque()
        for i in range(n):
            if(i%2!=0):
                   d.appendleft(i)
            else:
                   d.append(i)
        print(d)

 

<think>我们被要求解释双向队列deque)的使用和实现。根据引用的资料,我们可以总结以下几点:1.**双向队列的定义**:双向队列deque)全称为doubleendedqueue,即双端队列。它允许在队列的两端(头部和尾部)进行插入和删除操作。2.**双向队列的用途**:-可以用作队列(FIFO,先进先出):从一端入队,另一端出队。-可以用作栈(LIFO,后进先出):从同一端入队和出队(通常为队尾)。-由于其灵活性,可以支持多种数据结构的操作。3.**实现类比较**(根据引用[2]和[3]):-`ArrayDeque`:基于可变数组(循环数组)实现,在内存中连续存储,因此对于随机访问性能较好。适合单线程环境下频繁的两端操作。-`LinkedList`:基于双向链表实现,支持快速的插入和删除,但访问元素需要遍历,所以随机访问性能较差。同时它也实现了List接口,因此支持列表操作。-`ConcurrentLinkedDeque`:线程安全的双向队列,使用无锁算法实现,适合高并发环境。-`LinkedBlockingDeque`:线程安全且支持阻塞操作,当队列为空时,取操作会被阻塞;当队列满时,插入操作会被阻塞。4.**双向队列的基本操作**(参考引用[3]和[4]):-插入操作:`addFirst(e)`,`offerFirst(e)`,`addLast(e)`,`offerLast(e)`-删除操作:`removeFirst()`,`pollFirst()`,`removeLast()`,`pollLast()`-获取元素(不删除):`getFirst()`,`peekFirst()`,`getLast()`,`peekLast()`注意:有两套方法,一套在操作失败时抛出异常(例如`addFirst`,`removeFirst`,`getFirst`),另一套在操作失败时返回特殊值(例如`offerFirst`返回false,`pollFirst`返回null,`peekFirst`返回null)。5.**Python中的双向队列**(引用[4]):-Python的标准库`collections`提供了`deque`模块。-示例操作:`append`(右端添加)、`appendleft`(左端添加)、`pop`(右端移除)、`popleft`(左端移除)等。-示例中还有旋转操作:`rotate`,可以旋转队列中的元素。现在,我们将按照用户要求,介绍双向队列的使用和实现,注意结合引用内容,并在适当位置添加引用标识。由于用户提到了实现,我们可以简要描述两种主要实现方式:基于循环数组(如ArrayDeque)和基于双向链表(如LinkedList)。**使用示例**:我们可以提供Java和Python的简单代码示例。最后,按照要求生成相关问题。注意:回答结构要清晰,使用中文。</think> ### 双向队列Deque)的使用与实现详解 #### 一、双向队列的定义与特性 双向队列Deque, Double Ended Queue)支持在队列头部和尾部同时进行元素**插入/删除操作**,兼具队列(FIFO)和栈(LIFO)的特性。其核心特点包括: - **双端操作**:支持 `addFirst`/`addLast`(头部/尾部插入)、`removeFirst`/`removeLast`(头部/尾部删除)[^3] - **灵活应用**:可替代栈(`push` = `addFirst`, `pop` = `removeFirst`)或普通队列(`offer` = `addLast`, `poll` = `removeFirst`)[^3] - **性能优势**:在两端操作的场景下时间复杂度为 $O(1)$[^1] #### 二、双向队列的实现方式 ##### 1. 基于循环数组(如 Java 的 `ArrayDeque`) - **数据结构**:使用环形数组存储元素 - **代码示例(Java)**: ```java public class ArrayDeque<E> { private E[] elements; private int head; // 头指针 private int tail; // 尾指针 public void addFirst(E e) { head = (head - 1 + capacity) % capacity; // 头指针前移 elements[head] = e; } public void addLast(E e) { elements[tail] = e; tail = (tail + 1) % capacity; // 尾指针后移 } } ``` **适用场景**:单线程下高频两端操作(内存连续访问高效)[^2] ##### 2. 基于双向链表(如 Java 的 `LinkedList`) - **数据结构**: ```mermaid graph LR A[HEAD] ⇄ B[Node1] ⇄ C[Node2] ⇄ D[TAIL] ``` - **操作逻辑**: - `addFirst`:创建新节点指向原头节点 - `removeLast`:断开尾节点并更新指针 - **适用场景**:需要频繁插入删除或链表特性的场景[^2] ##### 3. 线程安全实现(高并发场景) - `ConcurrentLinkedDeque`:无锁并发(CAS 实现),用于多线程任务窃取[^2] - `LinkedBlockingDeque`:支持容量限制和阻塞等待 #### 三、双向队列的使用示例 ##### Python 操作(引用 `collections.deque`[^4]) ```python from collections import deque d = deque([1,2,3], maxlen=5) # 初始化最大长度 d.append(4) # 尾部添加: [1,2,3,4] d.appendleft(0) # 头部添加: [0,1,2,3,4] d.pop() # 尾部删除 → 4 d.popleft() # 头部删除 → 0 d.rotate(2) # 循环右移: [3,4,1,2] ``` ##### Java 操作(引用 `Deque` 接口[^3]) ```java Deque<Integer> deque = new ArrayDeque<>(); deque.push(10); // 头部插入 = addFirst() deque.offer(20); // 尾部插入 = addLast() int first = deque.peekFirst(); // 获取头部元素 int last = deque.pollLast(); // 删除尾部元素 ``` #### 四、关键选择建议(根据引用[^2]) | **场景需求** | **推荐实现类** | **核心优势** | |---------------------------|----------------------|------------------------------| | 高频次两端操作(单线程) | `ArrayDeque` | 内存连续,随机访问 $O(1)$ | | 需要链表特性(索引访问) | `LinkedList` | 支持任意位置插入/删除 | | 高并发非阻塞 | `ConcurrentLinkedDeque` | 无锁并发,任务窃取 | | 阻塞式有界队列 | `LinkedBlockingDeque` | 容量限制 + 阻塞等待 | #### 五、典型应用场景 1. **撤销操作栈**:使用 `push`/`pop` 实现编辑历史管理 2. **任务调度系统**:支持从队头取任务,队尾添加紧急任务 3. **滑动窗口算法**:高效维护窗口边界(如 LeetCode 239) ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值