C++之stack等容器适配器(上)实战篇
前言:在C++17标准下,栈(stack)和队列(queue)作为STL容器适配器,通过封装底层序列容器(默认deque)实现了严格的数据结构约束:栈遵循LIFO原则仅开放push/pop/top操作,队列遵循FIFO原则限定front/back访问。其实现核心在于模板参数推导机制(CTAD)和适配器模式,通过限制底层容器的接口来保证数据结构纯度,同时支持用户选择list等替代实现以优化特定场景性能,如高频插入删除时采用list可避免deque的内存块重组开销,这种设计使STL既保持了抽象统一性又提供了底层调优的灵活性。
目录
一、栈:Stack
top
push/pop/empty
size
二、队列:Queue
front
back
push/pop
三、优先级队列:priority_queue
top
push/pop
一、栈:Stack
栈的结构我们在数据结构初阶就已经有过初步的了解了,这里我们主要来了解stl下的stack的使用以及文档。
C++ 标准模板库(STL)中关于 stack容器适配器相关知识,主要可以分为以下三个部分:
成员函数:stack自身定义的操作接口。
如:构造、判空、获取大小、访问 / 操作栈顶等,是直接操作栈的基础。
非成员函数重载:为stack适配的外部函数重载,拓展交互场景。
如:比较、IO 等运算符
非成员类特化:针对stack特性,对通用模板类做特化,适配泛型体系 。
如:哈希、仿函数适配等
具体如下图:
在C++STL容器中,为我们提供了 Stack 的接口函数,与 list、Vector、string类似,直接实例化使用即可,下面我们来学习 Stack 的常用接口:
top
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <stack> int main()
{std::stack<int> mystack;mystack.push(10);mystack.push(20);mystack.top() -= 5;std::cout << "现在栈顶的元素是:" << mystack.top() << '\n';return 0;
push/pop/empty
// stack::push/pop
#include <iostream>
#include <stack> int main()
{std::stack<int> mystack;for (int i = 0; i < 5; ++i){mystack.push(i);}std::cout << "从栈中弹出元素..." << std::endl;while (!mystack.empty()){std::cout << mystack.top() << ' ';mystack.pop();}std::cout << '\n';return 0;
}
size
// stack::size
#include <iostream>
#include <stack> int main()
{std::stack<int> myints;std::cout << "初始状态下的size: " << myints.size() << '\n';for (int i = 0; i < 5; i++){myints.push(i);}std::cout << "入栈元素后的size: " << myints.size() << '\n';myints.pop();std::cout << "出栈元素后的size: " << myints.size() << '\n';return 0;
}
二、队列:Queue
cplusplus网站上关于容器适配器queue的介绍:queue - C++ 参考
C++ 标准模板库(STL)中关于 queue容器适配器相关知识,主要可以分为以下三个部分:
成员函数:queue自身定义的操作接口。
如:构造、判空、访问及操作队头 / 队尾元素等基础函数。非成员函数重载:为queue适配的外部函数,拓展交互场景。
如:比较、IO 运算符等非成员类特化:针对queue特性,对通用模板类做特化,适配泛型体系 。
如:哈希、仿函数适配等
front
// queue::front
#include <iostream>
#include <queue> int main()
{std::queue<int> myqueue;myqueue.push(77);myqueue.push(16);myqueue.front() -= myqueue.back(); // 77-16=61std::cout << "现在的队头元素是:" << myqueue.front() << '\n';return 0;
}
back
// queue::back
#include <iostream>
#include <queue> int main()
{std::queue<int> myqueue;myqueue.push(12);myqueue.push(75); myqueue.back() -= myqueue.front();std::cout << "现在的队尾元素是:" << myqueue.back() << '\n';return 0;
}
push/pop
// queue::push/pop
#include <iostream>
#include <queue> int main()
{std::queue<int> myqueue;int myint;std::cout << "请输入一些整数(输入 0 以结束):\n";do {std::cin >> myint;myqueue.push(myint);} while (myint);std::cout << "myqueue队列中的内容是: ";while (!myqueue.empty()){std::cout << ' ' << myqueue.front();myqueue.pop();}std::cout << '\n';return 0;
}
size和empty同上
三、优先级队列:priority_queue
1.优先队列是一种容器适配器,根据严格的弱排序标准,它的第一个元素总是它所包含的元素中最大的。
2. 此上下文类似于堆,在堆中可以随时插入元素,并且只能检索最大堆元素(优先队列中位于顶部的元 素)。
3. 优先队列被实现为容器适配器,容器适配器即将特定容器类封装作为其底层容器类,queue提供一组特 定的成员函数来访问其元素。元素从特定容器的“尾部”弹出,其称为优先队列的顶部。
4. 底层容器可以是任何标准容器类模板,也可以是其他特定设计的容器类。容器应该可以通过随机访问迭 代器访问,并支持以下操作:
empty():检测容器是否为空
size():返回容器中有效元素个数
front():返回容器中第一个元素的引用
push_back():在容器尾部插入元素
C++ 标准模板库中关于 priority_queue容器适配器相关知识,主要可以分为以下三个部分:
成员函数:构造 / 查询 / 元素操作(top/push/pop等)
非成员函数重载:适配关系运算、输入输出等外部交互
非成员类特化:定制比较器(大 / 小顶堆)、选择底层容器(默认vector)
top
// priority_queue::top
#include <iostream>
#include <queue> //std::priority_queue 注意:“优先队列”存在于“头文件queue”中int main()
{std::priority_queue<int> mypq;mypq.push(10);mypq.push(20);mypq.push(15);std::cout << "现在优先队列中的队头的元素是:" << mypq.top() << '\n';return 0;
}
push/pop
// priority_queue::push/pop
#include <iostream>
#include <queue> int main()
{std::priority_queue<int> mypq;mypq.push(30);mypq.push(100);mypq.push(25);mypq.push(40);std::cout << "从优先队列中出队元素..." << std::endl;while (!mypq.empty()){std::cout << mypq.top() << " ";mypq.pop();}std::cout << '\n';return 0;
}