双端队列(deque)链表实现

本文详细介绍了双端队列的概念及其在单链表中的实现方式,包括头部和尾部的添加与删除操作。

我们知道栈和队列都是受限的线性表,

栈是只能尾部添加,删除元素.

队列是只能尾部添加元素,头部删除元素.

那假如想要头部和尾部都可以添加和删除元素呢? 于是就出现了双端队列.双端队列主要功能如下:

void EnQueHead(T val);//头部添加元素

void EnQueEnd(T val); //尾部添加元素

T DeQueHead();//头部删除元素

T DeQueEnd(); //尾部删除元素

 

 

 

双端队列单链表实现

单链表定义见:http://blog.youkuaiyun.com/weiwenhp/article/details/8634469

 

#include "LinkList.h"

template<class T>

class DQue

{

private:

LinkList<T> m_pList;

public:

void EnQueHead(T val){m_pList.InsertAt(0,val);}

void EnQueEnd(T val){m_pList.Add(val);}

T GetEnd(){return m_pList.GetTailVal();}

T GetHead(){return m_pList.GetHeadVal();}

 

T DeQueHead(){

T val = m_pList.GetHeadVal();

m_pList.RemoveAt(0);

return val;

}

T DeQueEnd(){

T val = m_pList.GetTailVal();

m_pList.Remove();

return val;

}

 

int Size(){ return m_pList.Size();}

void Clear() { m_pList.Clear(); }

};

/* * 基于双向链表实现双端队列结构 */ package dsa; public class Deque_DLNode implements Deque { protected DLNode header;//指向头节点(哨兵) protected DLNode trailer;//指向尾节点(哨兵) protected int size;//队列中元素的数目 //构造函数 public Deque_DLNode() { header = new DLNode(); trailer = new DLNode(); header.setNext(trailer); trailer.setPrev(header); size = 0; } //返回队列中元素数目 public int getSize() { return size; } //判断队列是否为空 public boolean isEmpty() { return (0 == size) ? true : false; } //取首元素(但不删除) public Object first() throws ExceptionQueueEmpty { if (isEmpty()) throw new ExceptionQueueEmpty("意外:双端队列为空"); return header.getNext().getElem(); } //取末元素(但不删除) public Object last() throws ExceptionQueueEmpty { if (isEmpty()) throw new ExceptionQueueEmpty("意外:双端队列为空"); return trailer.getPrev().getElem(); } //在队列前端插入新节点 public void insertFirst(Object obj) { DLNode second = header.getNext(); DLNode first = new DLNode(obj, header, second); second.setPrev(first); header.setNext(first); size++; } //在队列后端插入新节点 public void insertLast(Object obj) { DLNode second = trailer.getPrev(); DLNode first = new DLNode(obj, second, trailer); second.setNext(first); trailer.setPrev(first); size++; } //删除首节点 public Object removeFirst() throws ExceptionQueueEmpty { if (isEmpty()) throw new ExceptionQueueEmpty("意外:双端队列为空"); DLNode first = header.getNext(); DLNode second = first.getNext(); Object obj = first.getElem(); header.setNext(second); second.setPrev(header); size--; return(obj); } //删除末节点 public Object removeLast() throws ExceptionQueueEmpty { if (isEmpty()) throw new ExceptionQueueEmpty("意外:双端队列为空"); DLNode first = trailer.getPrev(); DLNode second = first.getPrev(); Object obj = first.getElem(); trailer.setPrev(second); second.setNext(trailer); size--; return(obj); } //遍历 public void Traversal() { DLNode p = header.getNext(); while (p != trailer) { System.out.print(p.getElem()+" "); p = p.getNex
### 双端队列 Deque 数据结构 #### 定义 双端队列 (Deque, Double-ended Queue) 是一种可以从两端进行插入和删除操作的线性数据结构[^1]。这种特性使得它可以灵活地处理多种类型的队列需求。 #### 基本操作 双端队列支持如下基本操作: - `push_front(x)`:在前端插入元素 x。 - `pop_front()`:移除并返回前端元素。 - `push_back(x)`:在后端插入元素 x。 - `pop_back()`:移除并返回后端元素。 - `empty()`:判断双端队列是否为空。 - `size()`:获取当前存储元素的数量。 这些操作的时间复杂度通常为 O(1),这得益于内部采用的高效实现机制。 #### 实现方式 双端队列可以通过两种主要的方式实现——基于数组或者链表。每种方法都有各自的优劣之处: - **数组实现**:通过动态分配连续内存来模拟双端队列的行为,适合于已知大小范围的情况;但在频繁增删时可能会引发大量的内存复制开销。 - **链表实现**:利用节点之间的指针链接形成双向循环列表,允许任意位置快速插入/删除而不必担心内存重定位问题,更适合未知规模的数据集。 对于 C++ 中的标准库容器 `std::deque` 而言,则采用了分段管理的技术方案,在保持随机访问特性的前提下优化了性能表现[^2]。 然而值得注意的是,由于 `std::deque` 的特殊设计,当涉及到大量遍历操作时,其效率相对较低,因为每次迭代都需要额外检查是否跨越了某个小块区域的边界[^3]。 #### 应用场景 尽管存在上述局限性,双端队列仍然有着广泛的应用领域: - 作为标准模板库(STL)中栈(stack)队列(queue)的基础实现之一; - 处理需要同时维护最新与最旧记录的任务调度算法; - 缓存淘汰策略中的 LRU(Least Recently Used)缓存管理; - 图形界面应用程序的消息传递系统等[^4]。 ```cpp // 创建一个简单的 C++ std::deque 并执行一些基础操作 #include <iostream> #include <deque> int main() { std::deque<int> d; // 插入几个整数到 deque 尾部 for(int i=0; i<5; ++i){ d.push_back(i); } // 输出所有元素 while(!d.empty()){ std::cout << d.front() << ' '; d.pop_front(); } return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值