队列(先进先出)
队列queue
- 一些基础操作:
#include <iostream>
#include <queue> // 引入队列头文件
using namespace std;
int main() {
// 定义一个int类型的队列
queue<int> q;
// 入队:push()在队尾添加元素
q.push(10);
q.push(20);
q.push(30);
// 查看队首元素:front()不删除,查看对尾元素,back()不删除
cout << "队首元素:" << q.front() << endl; // 输出:10
// 查看队列大小:size()
cout << "队列大小:" << q.size() << endl; // 输出:3
// 出队:pop()(无返回值,需先通过front()获取元素)
q.pop();
cout << "出队后队首元素:" << q.front() << endl; // 输出:20
// 判断队列是否为空:empty()(空则返回true)
while (!q.empty()) {
cout << "出队元素:" << q.front() << endl;
q.pop();
}
// 输出:
// 出队元素:20
// 出队元素:30
return 0;
}
- 双端队列
#include <iostream>
#include <deque>
using namespace std;
int main() {
deque<int> dq;
// 从队尾插入元素
dq.push_back(10); // dq: [10]
dq.push_back(20); // dq: [10, 20]
// 从队首插入元素
dq.push_front(5); // dq: [5, 10, 20]
// 访问队首和队尾元素
cout << "队首:" << dq.front() << endl; // 输出:5
cout << "队尾:" << dq.back() << endl; // 输出:20
// 从队首删除元素
dq.pop_front(); // dq: [10, 20]
// 从队尾删除元素
dq.pop_back(); // dq: [10]
// 遍历队列
for (int num : dq) {
cout << num << " "; // 输出:10
}
return 0;
}
- 单调队列
示例:用单调队列解决滑动窗口最大值
以 nums = [1,3,-1,-3,5,3,6,7],k=3 为例,维护一个单调递减队列(队首为当前窗口最大值):
#include <iostream>
#include <vector>
#include <deque>
using namespace std;
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
vector<int> res;
deque<int> dq; // 存储索引,对应元素单调递减
for (int i = 0; i < nums.size(); ++i) {
// 1. 移除窗口外的元素(队首超出范围则弹出)
if (!dq.empty() && dq.front() <= i - k) {
dq.pop_front();
}
// 2. 维护单调性:移除队尾小于当前元素的索引(它们不可能是最大值)
while (!dq.empty() && nums[dq.back()] <= nums[i]) {
dq.pop_back();
}
// 3. 加入当前元素索引
dq.push_back(i);
// 4. 窗口形成后(i >= k-1),记录队首最大值
if (i >= k - 1) {
res.push_back(nums[dq.front()]);
}
}
return res;
}
int main() {
vector<int> nums = {1,3,-1,-3,5,3,6,7};
int k = 3;
vector<int> res = maxSlidingWindow(nums, k);
for (int num : res) {
cout << num << " "; // 输出:3 3 5 5 6 7
}
return 0;
}
数组模拟队列
#include <iostream>
using namespace std;
const int MAX_SIZE = 100; // 队列最大容量
class ArrayQueue {
private:
int data[MAX_SIZE]; // 存储队列元素的数组
int front; // 队首指针(指向队首元素)
int rear; // 队尾指针(指向队尾元素的下一个位置)
int size; // 当前队列元素个数
public:
// 构造函数:初始化队列
ArrayQueue() {
front = 0;
rear = 0;
size = 0;
}
// 入队:在队尾添加元素
bool enqueue(int value) {
if (isFull()) { // 队列满了则无法入队
cout << "队列已满,无法入队!" << endl;
return false;
}
data[rear] = value; // 将元素放入队尾位置
rear = (rear + 1) % MAX_SIZE; // 队尾指针后移(循环队列处理)
size++;
return true;
}
// 出队:移除队首元素
bool dequeue() {
if (isEmpty()) { // 队列为空则无法出队
cout << "队列为空,无法出队!" << endl;
return false;
}
front = (front + 1) % MAX_SIZE; // 队首指针后移(循环队列处理)
size--;
return true;
}
// 获取队首元素
int getFront() {
if (isEmpty()) {
cout << "队列为空,无队首元素!" << endl;
return -1; // 错误标记
}
return data[front];
}
// 判断队列是否为空
bool isEmpty() {
return size == 0;
}
// 判断队列是否已满
bool isFull() {
return size == MAX_SIZE;
}
// 获取队列当前元素个数
int getSize() {
return size;
}
};
// 测试数组队列
int main() {
ArrayQueue q;
q.enqueue(10);
q.enqueue(20);
q.enqueue(30);
cout << "队首元素:" << q.getFront() << endl; // 输出:10
cout << "队列大小:" << q.getSize() << endl; // 输出:3
q.dequeue();
cout << "出队后队首元素:" << q.getFront() << endl; // 输出:20
return 0;
}
链表模拟队列
#include <iostream>
using namespace std;
// 链表节点结构
struct Node {
int data; // 节点值
Node* next; // 指向下一个节点的指针
Node(int val) : data(val), next(nullptr) {} // 构造函数
};
class LinkedQueue {
private:
Node* front; // 队首指针(指向第一个节点)
Node* rear; // 队尾指针(指向最后一个节点)
int size; // 当前队列元素个数
public:
// 构造函数:初始化队列
LinkedQueue() {
front = nullptr;
rear = nullptr;
size = 0;
}
// 析构函数:释放所有节点内存
~LinkedQueue() {
while (front != nullptr) {
Node* temp = front;
front = front->next;
delete temp;
}
}
// 入队:在队尾添加元素
void enqueue(int value) {
Node* newNode = new Node(value); // 创建新节点
if (isEmpty()) { // 若队列为空,队首和队尾都指向新节点
front = newNode;
rear = newNode;
} else { // 否则,队尾节点的next指向新节点,再更新队尾指针
rear->next = newNode;
rear = newNode;
}
size++;
}
// 出队:移除队首元素
bool dequeue() {
if (isEmpty()) {
cout << "队列为空,无法出队!" << endl;
return false;
}
Node* temp = front; // 临时保存队首节点
front = front->next; // 队首指针后移
delete temp; // 释放原队首节点内存
size--;
// 若队列空了,队尾指针也置空
if (front == nullptr) {
rear = nullptr;
}
return true;
}
// 获取队首元素
int getFront() {
if (isEmpty()) {
cout << "队列为空,无队首元素!" << endl;
return -1; // 错误标记
}
return front->data;
}
// 判断队列是否为空
bool isEmpty() {
return size == 0;
}
// 获取队列当前元素个数
int getSize() {
return size;
}
};
// 测试链表队列
int main() {
LinkedQueue q;
q.enqueue(100);
q.enqueue(200);
q.enqueue(300);
cout << "队首元素:" << q.getFront() << endl; // 输出:100
cout << "队列大小:" << q.getSize() << endl; // 输出:3
q.dequeue();
cout << "出队后队首元素:" << q.getFront() << endl; // 输出:200
return 0;
}