stack,queue,list的区别和联系

一、总体概览

类型 所属类别 底层实现(默认) 访问模式 特点
stack 容器适配器 deque LIFO(后进先出) 只在一端(栈顶)操作
queue 容器适配器 deque FIFO(先进先出) 队尾插入、队头删除
list 序列容器 双向链表 双向顺序访问 任意位置高效插入/删除,不支持随机访问

stackqueue 属于容器适配器 ,它们通过封装底层容器(默认 deque)来提供特定的接口。

list独立的容器,直接管理内存。


二、区别与联系

1. 区别

特性 stack queue list
元素访问 只能访问栈顶 top() 只能访问队头 front() 和队尾 back() 双向迭代,可用 begin()/end() 遍历所有元素
插入操作 push()(只从顶部) push()(只从尾部) push_front() / push_back() / insert()
删除操作 pop()(只从顶部) pop()(只从头部) pop_front() / pop_back() / erase()
随机访问 ❌ 不支持 ❌ 不支持 ❌ 不支持(但可用迭代器遍历)
底层结构 默认 deque,也可用 vector/list 默认 deque,也可用 list 双向链表
迭代器支持 ❌ 无迭代器 ❌ 无迭代器 ✅ 双向迭代器
常用场景 深度优先搜索、表达式求值 广度优先搜索、任务队列 需要频繁中间插入/删除的序列

2. 联系

  • 三者都位于 <stack><queue><list> 头文件中。

  • 都是模板类,可存储任意类型元素。

  • 都提供 empty()size() 成员函数。

  • stackqueue 可以基于 list 实现:stack<int, list<int>>

  • 三者都不支持随机访问迭代器。


三、stack 详解

定义

cpp 复制代码
#include <stack>
std::stack<T, Container> s;   // Container 默认 deque<T>

常用接口

函数 说明 返回值
push(const T& val) val 压入栈顶 void
pop() 弹出栈顶元素(无返回值) void
top() 返回栈顶元素的引用 T& / const T&
empty() 判断栈是否为空 bool
size() 返回栈中元素个数 size_type

示例

cpp 复制代码
std::stack<int> st;
st.push(1);
st.push(2);
int top = st.top(); // 2
st.pop();           // 弹出2

四、queue 详解

定义

cpp 复制代码
#include <queue>
std::queue<T, Container> q;   // Container 默认 deque<T>

常用接口

函数 说明 返回值
push(const T& val) val 放入队尾 void
pop() 弹出队头元素(无返回值) void
front() 返回队头元素的引用 T& / const T&
back() 返回队尾元素的引用 T& / const T&
empty() 判断队列是否为空 bool
size() 返回队列中元素个数 size_type

示例

cpp 复制代码
std::queue<int> q;
q.push(1);
q.push(2);
int front = q.front(); // 1
int back = q.back();   // 2
q.pop();               // 移除1

五、list 详解

定义

cpp 复制代码
#include <list>
std::list<T> lst;

常用接口(按功能分组)

1. 迭代器(遍历用)
函数 说明
begin() / end() 正向迭代器
rbegin() / rend() 反向迭代器
cbegin() / cend() const 正向迭代器
2. 容量
函数 说明
empty() 是否为空
size() 元素个数
3. 访问(仅支持首尾直接访问)
函数 说明
front() 返回第一个元素的引用
back() 返回最后一个元素的引用
4. 插入与删除
函数 说明
push_front(const T& val) 头部插入
pop_front() 删除头部元素
push_back(const T& val) 尾部插入
pop_back() 删除尾部元素
insert(pos, val) 在迭代器 pos 位置插入 val(支持多个重载)
erase(pos) / erase(first, last) 删除一个或一段元素
clear() 清空所有元素
5. 特殊操作(链表特有)
函数 说明
splice(pos, other) 将另一个 list 的元素移动到 pos
remove(const T& val) 删除所有等于 val 的元素
remove_if(predicate) 删除满足条件的元素
unique() 删除连续的重复元素(需先排序)
merge(other) 合并两个已排序的 list
sort() 对元素排序(不支持 std::sort,用自己的成员函数)
reverse() 反转链表

示例

cpp 复制代码
std::list<int> lst = {1, 2, 3, 2, 4};
lst.push_front(0);          // 0,1,2,3,2,4
lst.remove(2);              // 删除所有2 -> 0,1,3,4
lst.sort();                 // 0,1,3,4
lst.reverse();              // 4,3,1,0

// 用迭代器遍历
for (auto it = lst.begin(); it != lst.end(); ++it) {
    std::cout << *it << " ";
}

六、使用建议与注意事项

  1. 需要 LIFO 行为stack
    需要 FIFO 行为queue
    需要任意位置插入删除,或需要双向迭代list

  2. stackqueue 不提供迭代器 ,因此不能遍历内部元素(除非通过 pop 逐个取出)。

  3. list 的插入/删除不会使迭代器失效(除了指向被删除元素的迭代器),这是它相对于 vector 的一大优势。

  4. 若想要随机访问,应使用 vectordeque,而非 list

  5. 三者都支持自定义底层容器,例如:

    cpp 复制代码
    std::stack<int, std::vector<int>> st;   // 基于 vector
    std::queue<int, std::list<int>> q;      // 基于 list

七、总结表格

操作 stack queue list
头部插入 push_front
尾部插入 push push push_back
中间插入 insert
头部删除 pop pop_front
尾部删除 pop pop_back
访问任意位置 ❌ (需迭代器)
访问首元素 front front
访问末元素 top back back
遍历所有元素 ✅ 迭代器
是否适配器
相关推荐
牛油果子哥q4 小时前
AVL平衡树与红黑树深度精讲对比,平衡因子、四大旋转原理、着色规则、平衡策略、性能差异与面试手撕全解
数据结构·c++·面试
汉克老师5 小时前
GESP7级C++考试语法知识(二、指数函数(3、综合练习)
c++·算法·数学建模·指数函数·gesp7级·复利
C++ 老炮儿的技术栈5 小时前
Ubuntu root账号自动登陆
linux·运维·服务器·c语言·c++·ubuntu·visual studio
Irissgwe5 小时前
map/set/multimap/multiset 的底层逻辑与实现
数据结构·c++·算法·二叉树·stl·c·红黑树
IronMurphy6 小时前
【算法五十八】23. 合并 K 个升序链表
数据结构·算法·链表
凡人叶枫6 小时前
Effective C++ 条款39:明智而审慎地使用 private 继承
java·数据库·c++·嵌入式开发
不想写代码的星星6 小时前
伪共享:逻辑无共享,物理打成狗
c++
noipp7 小时前
【无标题】
c语言·数据结构·c++·算法
森G7 小时前
64、完善聊天室程序(TLV拓展)---------网络编程
网络·c++·tcp/ip
郝学胜-神的一滴7 小时前
完全二叉树与堆底层原理深度剖析 | 手写C++大顶堆实现
java·开发语言·数据结构·c++·python·算法