什么是容器适配器?

定义

容器适配器不是“新容器”,而是对已有容器的接口封装
用来限制功能、改变访问方式,从而形成特定的数据结构语义

适配器对应数据结构
stack栈(LIFO)
queue队列(FIFO)
priority_queue优先级队列(堆)

适配器

复用已有实现,不暴露其全部接口,只提供“需要的那部分能力”

👉 STL 的容器适配器:

  • 内部用的是已有容器

  • 对外只暴露特定接口

  • 刻意隐藏 iterator / 随机访问能力

为什么要设计容器适配器?

例子:用 vector 模拟栈

👉 vector 的接口“太自由”,无法约束使用者

vector<int> v;
v.push_back(1);
v.push_back(2);
v.pop_back();

v.insert(v.begin(), 100);  // ❌ 破坏“栈”的语义
v[0] = 999;                // ❌ 非法访问

容器适配器做了三件事:

  1. 限制接口(只给 push / pop / top)

  2. 固定访问规则(LIFO / FIFO / 优先级)

  3. 防止误用(根本不给 iterator)

STL 三大容器适配器详解

(一)stack —— 栈(LIFO)

1️⃣ 定义与本质

template<
    class T,
    class Container = deque<T>
> class stack;
  • 默认底层容器:deque

  • 也可以用:vectorlist

2️⃣ 对外接口(非常少)

接口说明
push(x)入栈
pop()出栈
top()访问栈顶
empty()是否为空
size()元素个数

3️⃣ 底层实现思想(本质)

template<class T, class Container>
class stack {
protected:
    Container c;  // 真正存数据的容器
public:
    void push(const T& x) { c.push_back(x); }
    void pop() { c.pop_back(); }
    T& top() { return c.back(); }
};

(二)queue—— 队列(FIFO)

1️⃣ 定义与本质

template<
    class T,
    class Container = deque<T>
> class queue;
  • 默认:deque

  • 不能用 vector(没有 pop_front

2️⃣ 对外接口

接口说明
push(x)入队(尾)
pop()出队(头)
front()队头
back()队尾
empty()判空
size()大小

3️⃣ 底层逻辑

void push(const T& x) { c.push_back(x); }
void pop() { c.pop_front(); }

(三)deque

1️⃣ 定义

deque(双端队列):是一种双开口的"连续"空间的数据结构,双开口的含义是:可以在头尾两端进行插入和删除操作,且时间复杂度为O(1),与vector比较,头插效率高,不需要搬移元素;与list比较,空间利用率比较高。deque并不是真正连续的空间,而是由一段段连续的小空间拼接而成的,实际deque类似于一个动态的二维数组

2️⃣ 缺陷

与vector比较,deque的优势是:

头部插入和删除时,不需要搬移元素,效率特别高,而且在扩容时,也不需要搬移大量的元素,因此其效率是必vector高的。

与list比较,其底层是连续空间,空间利用率比较高,不需要存储额外字段。

但是,deque有一个致命缺陷:

不适合遍历,因为在遍历时,deque的迭代器要频繁的去检测其是否移动到某段小空间的边界,导致效率低下,而序列式场景中,可能需要经常遍历,因此在实际中,需要线性结构 时,大多数情况下优先考虑vector和list,deque的应用并不多 。

3️⃣ 为什么选择deque作为stack和queue的底层默认容器

1. stack和queue不需要遍历(因此stack和queue没有迭代器),只需要在固定的一端或者两端进行操作。

2. 在stack中元素增长时,deque比vector的效率高(扩容时不需要搬移大量数据);

queue中的元素增长时,deque不仅效率高,而且内存使用率高。

(四)priority_queue —— 优先级队列(堆)

1️⃣ 定义(最重要)

template<
    class T,
    class Container = vector<T>,
    class Compare = less<T>
> class priority_queue;

默认是:

  • vector + 大根堆

  • top()最大值

2️⃣ 对外接口

接口说明
push(x)插入元素
pop()删除优先级最高元素
top()访问最高优先级
empty()判空
size()个数

3️⃣ 底层实现思想(核心) 本质是堆(heap)

push -> push_back -> adjust_up
pop  -> swap + pop_back -> adjust_down

容器适配器 vs 底层容器

维度容器容器适配器
是否存数据❌(只是封装)
是否有 iterator
接口是否自由极低
是否强调语义
是否可随机访问视容器

更多推荐