手把手实现C++ STL队列(queue):从底层容器到接口封装
·
前言
队列(Queue)是计算机科学中最基本的数据结构之一,它遵循先进先出(FIFO)的原则。在C++标准模板库(STL)中,std::queue是一个容器适配器,提供队列的功能。本文将深入探讨如何从零实现一个完整的队列类,并分析其设计思路和实现细节。
队列的基本概念
队列是一种线性数据结构,支持两种基本操作:
-
入队(push):在队列尾部添加元素
-
出队(pop):从队列头部移除元素
这种特性使得队列非常适合处理需要按顺序处理元素的场景,如任务调度、消息传递等。
实现详解
1. 命名空间和模板设计
cpp
#pragma once
#include <iostream>
#include <deque>
using namespace std;
namespace ym
{
template<class T, class container = deque<T>>
class queue
{
// 实现细节
};
}
-
#pragma once:防止头文件被多次包含 -
模板设计:使用类模板支持多种数据类型
-
默认容器:使用
deque作为默认底层容器,这是STL的标准做法 -
命名空间:自定义命名空间
ym避免与标准库命名冲突
2. 核心接口实现
入队操作(push)
cpp
void push(const T& x)
{
con.push_back(x);
}
使用底层容器的push_back方法,在队列尾部添加元素。
出队操作(pop)
cpp
void pop()
{
con.pop_front();
}
使用底层容器的pop_front方法,从队列头部移除元素。
访问操作
cpp
T& back()
{
return con.back();
}
T& front()
{
return con.front();
}
提供对队列头部和尾部元素的访问,返回引用允许修改元素值。
容量查询
cpp
size_t size() const
{
return con.size();
}
bool empty() const
{
return con.empty();
}
提供队列大小和空状态查询功能,const修饰符保证不修改对象状态。
3. 设计特点分析
-
容器适配器模式:queue不是独立的容器,而是基于其他容器的适配器
-
接口一致性:与STL queue保持相同的接口,便于替换和使用
-
异常安全:所有操作都依赖底层容器的实现,自然具有异常安全性
-
灵活性:通过模板参数可以指定不同的底层容器
底层容器选择
虽然默认使用deque,但queue也可以基于其他容器实现:
cpp
// 基于list实现 ym::queue<int, list<int>> list_queue; // 基于vector实现(需要提供pop_front实现) ym::queue<int, vector<int>> vector_queue;
不同底层容器的性能 characteristics:
-
deque:首尾操作O(1)时间复杂度,内存不连续
-
list:所有操作O(1)时间复杂度,内存开销较大
-
vector:尾部操作高效,但头部操作需要O(n)时间
使用示例
cpp
#include "queue.h"
int main()
{
ym::queue<int> q;
// 入队操作
for(int i = 1; i <= 5; ++i)
q.push(i);
// 访问元素
cout << "队首元素: " << q.front() << endl;
cout << "队尾元素: " << q.back() << endl;
// 出队操作
while(!q.empty())
{
cout << q.front() << " ";
q.pop();
}
return 0;
}
输出结果:
text
队首元素: 1 队尾元素: 5 1 2 3 4 5
与STL queue的对比
| 特性 | 本实现 | STL queue |
|---|---|---|
| 接口一致性 | 完全一致 | 标准接口 |
| 异常安全 | 依赖底层容器 | 强异常安全 |
| 可扩展性 | 可自定义容器 | 固定容器选择 |
| 性能 | 与底层容器相关 | 高度优化 |
更多推荐


所有评论(0)