当前位置: 首页 > news >正文

C++数据结构--队列

一.什么是队列

队列(Queue)是一种遵循先进先出(FIFO, First In First Out)原则的数据结构。队列通常有两种实现方式:顺序队列,环形队列与链式队列,各有优劣。但同时从底层来看队列并不是一种新的数据结构,环形队列的底层依靠数组,链式栈的底层依靠链表。(注意C++中的容器适配器queue,底层默认是deque(双向队列)是一个顺序队列,但是我们也可以将其设置成一个链式栈)

二.环形队列及其代码实现

原理:基于固定大小的数组实现,通过维护两个指针/索引,front(队头),和rear(队尾),核心思想:通过取模运算(%),使得当rear加到·队尾时,通过取模运算,能够将其回到队内存开始的地方存储,由此实现了类似于环的结构:rear = (rear + 1) % cap(cap是数组的容量),front = (front + 1) % cap,实际上的实现过程中,为了区分队空与满,我们需要空出一个存储空间,当front == rear,表示队空,(rear + 1) % 容量 == front表示队满;
优点:极高的空间利用率,操作效率极高,内存友好且稳定
缺点:容量固定,无法动态扩展,存在少量空间浪费

代码实现:如下图:

class Queue//环形队列 { public: Queue(int cap = 10) :m_cap(cap) ,m_front(0) ,m_rear(0) ,m_size(0) { pQue = new int[cap]; } ~Queue() { delete[]pQue; pQue = nullptr; } public: void push(int val)//入队 { if ((m_rear + 1) % m_cap == m_front) { expend(2 * m_rear); } pQue[m_rear] = val; m_rear = (m_rear + 1) % m_cap; m_size++; } void pop()//出队 { if (m_rear == m_front) throw "Queue is empty"; m_front = (m_front + 1) % m_cap; m_size--; } int front() const//获取队头元素 { if (m_rear == m_front) throw "Queue is empty"; return pQue[m_front]; } int back() const//获取队尾元素 { if (m_rear == m_front) throw "Queue is empty"; return pQue[(m_rear-1+m_cap)%m_cap]; } bool empty() const//判断是否为空 { return m_front == m_rear; } int size() const//获取元素个数 { return m_size; } void show()const//打印 { int p = m_front; while (p != m_rear) { cout << pQue[p] << " "; p = (p + 1) % m_cap; } cout << endl; } private: void expend(int val)//扩容 { int p = m_front; int* q = new int(val); int i = 0; while (p != m_rear) { q[i] = pQue[p]; p = (p + 1) % m_cap; i++; } delete[] pQue; pQue = q; m_cap = val; m_front = 0; m_rear = i; } private: int* pQue; int m_cap; int m_front; int m_rear; int m_size; };

三.链式栈及其代码实现

原理:基于双向循环链表实现,需要定义一个头节点,入队操作相于当尾插,出队操作相当于头删。
优点:操作效率极高,动态扩容,支持双向遍历
缺点:空间开销大,缓存友好性差

代码实现:如下图:

class LinkQueue { public: LinkQueue() { head = new Node(); head->next = head; head->pre = head; } ~LinkQueue() { Node* p = head->next; while (p!=head ) { head->next = p->next; p->next->pre = head; delete p; p = head->next; } delete head; head = nullptr; } public: void push(int val)//入队 { Node* node = new Node(val); Node* p = head->pre; p->next = node; node->pre = p; node->next = head; head->pre = node; m_size++; } void pop()//出队 { if (head->next == head) throw "Queue is empty"; Node* p = head->next; head->next = head->next->next; delete p; head->next->next->pre = head; m_size--; } int front() const//获取队头元素 { if (head->next == head) throw "Queue is empty"; return head->next->data; } int back() const//获取队尾元素 { if (head->next == head) throw "Queue is empty"; return head->pre->data; } bool empty() const//判断队列是否为空 { return head->next == head; } void show()const//打印 { Node* p = head->next; while (p->next != head) { cout << p->data << " "; p = p->next; } cout << endl; } int size() const//获取队列元素个数 { return m_size; } private: struct Node { Node(int val=0) :data(val) ,next(nullptr) ,pre(nullptr) { } int data; Node* next; Node* pre; }; Node* head; int m_size; };

四.典型问题

1. 用队列实现栈

class MyStack { public: MyStack() { } void push(int x) { q1.push(x); while(!q2.empty()) { q1.push(q2.front()); q2.pop(); } queue<int> q3; q2=q1; q1=q3; } int pop() { int val=q2.front(); q2.pop(); return val; } int top() { return q2.front(); } bool empty() { return q2.empty(); } private: queue<int> q1; queue<int> q2; };

2.用栈实现队列

class MyQueue { public: MyQueue() { } void push(int x) { s1.push(x); } int pop() { if(s2.empty()) { while(!s1.empty()) { s2.push(s1.top()); s1.pop(); } } int val=s2.top(); s2.pop(); return val; } int peek() { if(s2.empty()) { while(!s1.empty()) { s2.push(s1.top()); s1.pop(); } } return s2.top(); } bool empty() { return s1.empty()&&s2.empty(); } private: stack<int> s1; stack<int> s2; };
http://www.jsqmd.com/news/749207/

相关文章:

  • 实时视频生成技术:MotionStream框架解析与应用
  • 智能代理开发:从代码到AI行为模式的设计
  • Git实践——GitLab服务器的部署与使用
  • 密集图像描述技术:规则系统与强化学习的融合创新
  • FTRL与BFCL在线学习算法性能对比与工程实践
  • 全国cppm报考和scmp报考TOP1(怎么报名及流程) - 众智商学院课程中心
  • 别再死记硬背公式了!用MATLAB动画演示混频器如何‘搬动’频谱(附代码)
  • 逻辑谬误识别:合成数据增强与LLM训练实践
  • 2026年3P防爆空调技术解析:分体式防爆空调/单元式防爆空调/壁挂式防爆空调/多联式防爆空调/天井式防爆空调/选择指南 - 优质品牌商家
  • MotionStream:实时视频生成框架的技术解析与应用
  • 冷轧不锈钢卷深度技术分享:镜面不锈钢板、201 不锈钢卷、201不锈钢板、304 不锈钢卷、304不锈钢板、316L不锈钢卷选择指南 - 优质品牌商家
  • 11.5B参数、1.2EFLOPS、训练从数周压到数小时:他们把通用原子势训练带入Exascale时代
  • MoltLock分布式锁:现代应用的高性能并发控制解决方案
  • Legacy-iOS-Kit架构深度解析:5大模块实现旧设备系统降级与性能重塑
  • 从单口到四口:基于Xilinx FPGA的10G UDP多网卡方案设计与资源开销全解析(KU060/KU5P/ZU9EG实测)
  • 探索未来操作系统:从微内核到分布式架构的无限扩展性设计
  • AI智能体工作流管理:基于文件系统的上下文持久化与协作框架
  • OpenSubject视频数据集自动化筛选技术与工程实践
  • MetaClaw框架:实现大模型动态进化的双循环学习机制
  • Python 数据分析基础入门:《Excel Python:飞速搞定数据分析与处理》学习笔记系列(附录 A Conda 环境)
  • 基于MCP协议构建AI智能体与社交媒体API的安全交互网关
  • 2026年4月诚信的工业厂房搭建企业推荐,定制化门窗设计,厂房采光通风俱佳 - 品牌推荐师
  • 大语言模型计数能力解析与优化实践
  • 华为OD新系统机试真题 2026-04-08 【准备生日礼物】
  • 【优化求解】通过信号灯交叉路口的连接燃料电池混合动力车的生态驾驶双层凸优化附matlab代码
  • MoltLock:轻量级Go分布式锁库的设计原理与etcd实战
  • Cursor Free VIP终极指南:如何永久免费使用AI编程助手
  • 用eNSP模拟华为网络工程师面试题:手把手复现一个OSPF+RIP+BGP+NAT的综合实验
  • 视频生成中的运动控制技术与优化实践
  • Python脚本依赖管理新思路:manifest实现按需安装与自包含分发