news 2026/5/4 6:43:24

C++数据结构--队列

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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; };
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/4 6:42:33

腾讯CognitiveKernel-Pro:构建企业级大模型应用的核心引擎

1. 项目概述&#xff1a;从“大模型应用”到“认知内核”的跃迁最近在搞大模型应用落地的朋友&#xff0c;估计都绕不开一个核心痛点&#xff1a;想法很美好&#xff0c;但真要把一个大模型塞进你的业务流程里&#xff0c;让它稳定、可靠、可控地工作&#xff0c;那感觉就像在驯…

作者头像 李华
网站建设 2026/5/4 6:35:28

强化学习在多轮对话系统中的应用与优化

1. 项目背景与核心挑战在对话系统领域&#xff0c;多轮会话的连贯性一直是业界公认的技术难点。传统对话模型往往只能处理单轮或短序列的交互&#xff0c;当面对需要长期记忆和复杂推理的对话场景时&#xff0c;表现就会大打折扣。这就像让一个只擅长短跑冲刺的运动员突然去跑马…

作者头像 李华
网站建设 2026/5/4 6:33:29

手撕 Linux 信号量:从古老的 PV 原语到现代内核

一.信号量的基本概念我们要想理解什么是信号量&#xff0c;就要先了解什么是对资源的整体使用和对资源的局部使用&#xff0c;我们来看&#xff1a;在前面的章节中我们讲过ATM机的例子&#xff0c;现在我们在拿它来举例&#xff0c;ATM机这种小房间就是一个很好的对资源整体使用…

作者头像 李华
网站建设 2026/5/4 6:32:22

物联网Mesh网络API设计:轻量级抽象层实现跨平台设备通信

1. 项目概述&#xff1a;一个面向物联网的轻量级Mesh网络API最近在折腾一个智能家居项目&#xff0c;想把家里的几个传感器节点和控制器连成一个稳定、低功耗的本地网络。市面上的方案要么太重&#xff08;比如直接上MQTT云&#xff09;&#xff0c;要么太底层&#xff08;比如…

作者头像 李华
网站建设 2026/5/4 6:32:19

社交AI个性化推理引擎设计与优化实践

1. 项目背景与核心挑战社交推理类AI应用&#xff08;如虚拟聊天伴侣、游戏NPC等&#xff09;面临一个根本性矛盾&#xff1a;既要保持对话的逻辑一致性&#xff0c;又要适配不同用户的个性化偏好。传统方法通常采用固定规则或统一模型&#xff0c;导致交互体验生硬。我们团队在…

作者头像 李华