C++容器适配器

C++ 容器适配器详解

容器适配器(Container Adapters)是 C++ 标准库中的一种特殊容器,通过封装现有容器并限制其接口,提供特定数据结构的特性(如栈、队列等)。它们本身不是独立的容器,而是基于其他容器(如 dequevectorlist)实现的适配器模式的应用。


一、容器适配器的核心特点

  1. 接口受限
    仅暴露符合目标数据结构特性的操作(如栈的 pushpoptop)。
  2. 组合而非继承
    通过内部持有底层容器(如 deque)实现功能,而非继承。
  3. 不支持迭代器
    无法直接遍历元素,仅能通过适配器的接口操作。
  4. 底层容器可定制
    可指定适配器使用的底层容器类型(需满足特定要求)。

二、标准库中的容器适配器

C++ 提供了三种容器适配器:
stack(栈)queue(队列)priority_queue(优先队列)


1. stack(栈:LIFO 后进先出)
  • 默认底层容器deque

  • 支持操作

    s.push(x)  // 压栈
    s.pop()    // 弹栈(不返回元素)
    s.top()    // 查看栈顶元素
    s.empty()  // 是否为空
    s.size()   // 元素数量
    
  • 示例

    #include <stack>
    #include <vector>
    
    std::stack<int> s1; // 默认使用 deque
    std::stack<int, std::vector<int>> s2; // 使用 vector 作为底层容器
    
    s1.push(10);
    s1.push(20);
    std::cout << s1.top(); // 输出 20
    s1.pop();              // 移除 20
    
  • 底层容器要求
    必须支持 back()push_back()pop_back()(如 vectordequelist)。


2. queue(队列:FIFO 先进先出)
  • 默认底层容器deque

  • 支持操作

    q.push(x)  // 入队
    q.pop()    // 出队(不返回元素)
    q.front()  // 队首元素
    q.back()   // 队尾元素
    q.empty()  
    q.size()   
    
  • 示例

    #include <queue>
    #include <list>
    
    std::queue<int> q1; // 默认使用 deque
    std::queue<int, std::list<int>> q2; // 使用 list
    
    q1.push(10);
    q1.push(20);
    std::cout << q1.front(); // 输出 10
    q1.pop();                // 移除 10
    
  • 底层容器要求
    必须支持 front()back()push_back()pop_front()(如 dequelist)。


3. priority_queue(优先队列:元素按优先级排序)
  • 默认底层容器vector

  • 支持操作

    pq.push(x)  // 插入元素
    pq.pop()    // 移除最高优先级元素
    pq.top()    // 查看最高优先级元素
    pq.empty()  
    pq.size()   
    
  • 示例

    #include <queue>
    #include <functional> // 用于 greater<int>
    
    // 默认是大顶堆(降序)
    std::priority_queue<int> pq1; 
    
    // 小顶堆(需指定底层容器和比较函数)
    std::priority_queue<int, std::vector<int>, std::greater<int>> pq2;
    
    pq1.push(30);
    pq1.push(10);
    pq1.push(20);
    std::cout << pq1.top(); // 输出 30(最大值)
    
    pq2.push(30);
    pq2.push(10);
    std::cout << pq2.top(); // 输出 10(最小值)
    
  • 底层容器要求
    必须支持随机访问迭代器(如 vectordeque),且需指定比较函数(默认 std::less<T>)。


三、容器适配器 vs 普通容器

特性容器适配器普通容器(如 vector、deque)
接口受限,仅暴露特定操作完整,支持迭代器、随机访问等
数据结构特性严格遵循栈、队列等行为通用容器,无特定行为约束
迭代器支持不支持支持
底层实现基于其他容器封装直接管理内存和元素

四、底层容器选择建议

  1. stack
    • 默认 deque:平衡头尾操作效率。
    • 若需要连续内存:选择 vector(但 pop 时可能触发内存重分配)。
  2. queue
    • 默认 deque:高效的头尾插入删除。
    • 若需链表特性:选择 list
  3. priority_queue
    • 默认 vector:堆操作依赖随机访问。
    • 避免使用 list(不支持随机访问)。

五、应用场景

  1. stack
    • 函数调用栈、括号匹配、表达式求值(逆波兰式)。
  2. queue
    • 任务调度、BFS 广度优先搜索、缓冲池。
  3. priority_queue
    • 任务优先级调度、Dijkstra 最短路径算法、Top K 问题。

六、自定义比较函数(以 priority_queue 为例)

// 自定义结构体
struct Task {
    int priority;
    std::string name;
};

// 自定义比较函数(优先级小的先出队)
struct CompareTask {
    bool operator()(const Task& a, const Task& b) {
        return a.priority > b.priority; // 小顶堆
    }
};

std::priority_queue<Task, std::vector<Task>, CompareTask> task_queue;

task_queue.push({3, "Clean"});
task_queue.push({1, "Urgent"});
std::cout << task_queue.top().name; // 输出 "Urgent"

七、总结

  • 容器适配器是对现有容器的封装,提供特定数据结构的行为约束。
  • stackqueuepriority_queue 分别对应栈、队列、优先队列的经典操作。
  • 灵活选择底层容器以满足不同场景的性能需求。
  • 优先使用适配器而非手动实现数据结构,确保代码简洁且符合标准规范。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值