【C++】stack和queue

目录

1. stack的介绍和使用

1.1 stack的介绍

1.2 stack的使用

1.3 stack的模拟实现

2. queue的介绍和使用

2.1 queue的介绍

2.2 queue的使用

3. priority_queue的介绍和使用

3.1 priority_queue的介绍

3.2 priority_queue的使用

4. 容器适配器

4.1 什么是适配器

4.2 STL标准库中stack和queue的底层结构


1. stack的介绍和使用

1.1 stack的介绍

1.2 stack的使用

函数说明
接口说明
stack()
构造空的栈
empty()
检测 stack 是否为空
size()
返回 stack 中元素的个数
top()
返回栈顶元素的引用
push()
将元素 val 压入 stack
pop()
stack 中尾部的元素弹出

1.3 stack的模拟实现

从栈的接口中可以看出,栈实际是一种特殊的 vector ,因此使用 vector 完全可以模拟实现 stack

#include<vector>
namespace bite
{
    template<class T>
    class stack
    {
        public:
        stack() {}
        void push(const T& x) {_c.push_back(x);}
        void pop() {_c.pop_back();}
        T& top() {return _c.back();}
        const T& top()const {return _c.back();}
        size_t size()const {return _c.size();}
        bool empty()const {return _c.empty();}
    private:
        std::vector<T> _c;
    };
}

2. queue的介绍和使用

 

2.1 queue的介绍

翻译:
1. 队列是一种容器适配器,专门用于在 FIFO 上下文 ( 先进先出 ) 中操作,其中从容器一端插入元
素,另一端提取元素。
2. 队列作为容器适配器实现,容器适配器即将特定容器类封装作为其底层容器类, queue 提供
一组特定的成员函数来访问其元素。元素从队尾入队列,从队头出队列。
3. 底层容器可以是标准容器类模板之一,也可以是其他专门设计的容器类。该底层容器应至少
支持以下操作 :
        empty:检测队列是否为空
        size:返回队列中有效元素的个数
        front:返回队头元素的引用
        back:返回队尾元素的引用
        push_back:在队列尾部入队列
        pop_front:在队列头部出队列
4. 标准容器类 deque list 满足了这些要求。默认情况下,如果没有为 queue 实例化指定容器
类,则使用标准容器 deque

2.2 queue的使用

函数声明
接口说明
queue()
构造空的队列
empty()
检测队列是否为空,是返回 true ,否则返回 false
size()
返回队列中有效元素的个数
front()
返回队头元素的引用
back()
返回队尾元素的引用
push()
在队尾将元素 val 入队列
pop()
将队头元素出队列

3. priority_queue的介绍和使用

3.1 priority_queue的介绍

翻译:
1. 优先队列是一种容器适配器,根据严格的弱排序标准,它的第一个元素总是它所包含的元素
中最大的。
2. 此上下文类似于堆,在堆中可以随时插入元素,并且只能检索最大堆元素 ( 优先队列中位于顶
部的元素 )
3. 优先队列被实现为容器适配器,容器适配器即将特定容器类封装作为其底层容器类, queue
提供一组特定的成员函数来访问其元素。元素从特定容器的 尾部 弹出,其称为优先队列的
顶部。
4. 底层容器可以是任何标准容器类模板,也可以是其他特定设计的容器类。容器应该可以通过
随机访问迭代器访问,并支持以下操作:
        empty():检测容器是否为空
        size():返回容器中有效元素个数
        front():返回容器中第一个元素的引用
        push_back():在容器尾部插入元素
        pop_back():删除容器尾部元素
5. 标准容器类 vector deque 满足这些需求。默认情况下,如果没有为特定的 priority_queue
类实例化指定容器类,则使用 vector
6. 需要支持随机访问迭代器,以便始终在内部保持堆结构。容器适配器通过在需要时自动调用
算法函数 make_heap push_heap pop_heap 来自动完成此操作。

3.2 priority_queue的使用

优先级队列默认使用 vector 作为其底层存储数据的容器,在 vector 上又使用了堆算法将 vector
元素构造成堆的结构,因此 priority_queue 就是堆,所有需要用到堆的位置,都可以考虑使用
priority_queue 。注意:默认情况下 priority_queue 是大堆

函数声明
接口说明
priority_queue()/priority_queue(first, last)
构造一个空的优先级队列
empty( )
检测优先级队列是否为空,是返回 true ,否
则返回 false
top( )
返回优先级队列中最大 ( 最小元素 ) ,即堆顶元
push(x)
在优先级队列中插入元素 x
pop ( )
删除优先级队列中最大 ( 最小 ) 元素,即堆顶元
【注意】
1. 默认情况下, priority_queue 是大堆。

#include <vector>
#include <queue>
#include <functional> // greater算法的头文件
void TestPriorityQueue()
{
    // 默认情况下,创建的是大堆,其底层按照小于号比较
    vector<int> v{3,2,7,6,0,4,1,9,8,5};
    priority_queue<int> q1;
    for (auto& e : v)
        q1.push(e);
    cout << q1.top() << endl;
    // 如果要创建小堆,将第三个模板参数换成greater比较方式
    priority_queue<int, vector<int>, greater<int>> q2(v.begin(), v.end());
    cout << q2.top() << endl;
}

4. 容器适配器

4.1 什么是适配器

适配器是一种设计模式 ( 设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设
计经验的总结 ) 该种模式是将一个类的接口转换成客户希望的另外一个接口.

4.2 STL标准库中stackqueue的底层结构

虽然 stack queue 中也可以存放元素,但在 STL 中并没有将其划分在容器的行列,而是将其称为
容器适配器 ,这是因为 stack 和队列只是对其他容器的接口进行了包装, STL stack queue 默认
使用 deque ,比如:
### C++ 中 `stack` `queue` 的数据结构定义及用法 #### 定义与特性 在 C++ 标准库 `<stack>` `<queue>` 中,`std::stack` 是一种后进先出(LIFO, Last In First Out)的数据结构,而 `std::queue` 则是一种先进先出(FIFO, First In First Out)的数据结构。这两种容器适配器都基于其他标准容器(如 `std::deque` 或 `std::list`)来实现。 对于 `std::stack` 而言,默认底层容器为 `std::deque`[^1]。它提供了三个主要的操作函数:`push()` 用于向栈顶添加元素;`pop()` 用于移除栈顶元素;以及 `top()` 返回当前栈顶的元素值[^3]。 而对于 `std::queue` 来说,默认同样使用 `std::deque` 作为底层容器[^2]。它的基本操作包括:`push()` 将新元素加入到队列尾部;`front()` 获取队首元素;`back()` 获取队尾元素;以及通过调用 `pop()` 移除队首元素。 #### 使用方法对比 以下是两种数据结构的具体使用示例: ##### Stack 示例代码 ```cpp #include <iostream> #include <stack> using namespace std; int main() { stack<int> stk; stk.push(1); stk.push(2); stk.push(3); while (!stk.empty()) { cout << stk.top() << " "; // 输出顺序应为 3 2 1 stk.pop(); } return 0; } ``` ##### Queue 示例代码 ```cpp #include <iostream> #include <queue> using namespace std; int main() { queue<int> que; que.push(1); que.push(2); que.push(3); while (!que.empty()) { cout << que.front() << " "; // 输出顺序应为 1 2 3 que.pop(); } return 0; } ``` 上述两段程序分别展示了如何利用 `std::stack` 实现 LIFO 行为借助 `std::queue` 达成 FIFO 效果。 #### 主要区别总结 - **访问模式**: `std::stack` 只允许在一端进行插入删除操作,即遵循 LIFO 原则;相反地,`std::queue` 支持两端操作——一端入队另一端出队,体现 FIFO 特征。 - **功能范围**: 鉴于其单侧受限的特点,`std::stack` 更适合解决那些需要逆序处理或者递归模拟场景下的问题;而当面对诸如广度优先搜索(BFS)之类需按层次遍历的任务时,则更适合选用 `std::queue`[^4]。 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值