C++ STL之栈stack

一.概述

C++ 中的 std::stack 是一种容器适配器,提供了一种后进先出(LIFO, Last In First Out)的数据结构。它只允许在栈顶进行插入和删除操作,不支持随机访问
主要特性:

  • 后进先出(LIFO):最后插入的元素最先被访问或移除。
  • 栈顶操作:只能在栈顶插入、访问和移除元素。
  • 受限接口:std::stack 只提供插入、删除、访问栈顶、检查大小和判断是否为空等基本操作,不支持像 std::vector 这样的随机访问。

二.初始化

2.1头文件

#include <stack>

2.2初始化

stack支持多种初始化方式,默认使用deque作为底层容器。

stack<int> s1; //默认构造
stack<int> s2(s1);  //拷贝构造,使用s1初始化s2
stack<int> s3(move(s1));  // 使用移动语义初始化s3
stack<int, vector<int>> s4; //使用vector作为底层容器
stack<int, list<int>> s5; //使用list作为底层容器

vector<int> vec = {1, 2, 3, 4, 5};
stack<int, vector<int>> s6(vec); //使用已有的vector初始化

deque<int> deq = {6, 7, 8, 9, 10};
stack<int, deque<int>> s7(deq); //使用已有的deque初始化

三.成员函数

接口含义
top()访问栈顶元素。
size()返回栈中元素的个数。
empty()判断栈是否为空。如果栈为空,返回 true,否则返回 false。
pop()移除栈顶元素。
push()将元素压入栈顶。
swap(stack& other)交换两个栈的内容,两个栈必须具有相同的类型和底层容器。

四.遍历

4.1 破坏性的

通过 pop() 操作来访问每个栈顶元素并将其移除。

#include <iostream>
#include <stack>

using namespace std;

int main() {
    stack<int> s;
    s.push(10);
    s.push(20);
    s.push(30);
    while (!s.empty()) {
        cout << s.top() << " ";  // 访问栈顶元素
        s.pop();  // 移除栈顶元素
    }
    return 0;
}

/*
output:30 20 10 
*/

4.2 非破坏性的

为了不破坏原始栈,可以使用一个辅助栈来保存遍历时的内容。遍历时将元素从原栈弹出到辅助栈,遍历完成后再将元素从辅助栈弹回原栈。

#include <iostream>
#include <stack>

using namespace std;

int main() {
    stack<int> s;
    s.push(10);
    s.push(20);
    s.push(30);

    stack<int> temp;  // 辅助栈
    while (!s.empty()) {
        cout << s.top() << " ";  // 访问栈顶元素
        temp.push(s.top());  // 存入辅助栈
        s.pop();  // 从原栈中移除
    }
    cout << endl;
    // 将元素从辅助栈移回原栈,恢复原始状态
    while (!temp.empty()) {
        s.push(temp.top());
        temp.pop();
    }
    return 0;
}

/*
output:30 20 10 
*/

4.3 使用底层容器遍历(不推荐)

stack能够基于deque、vector 或list构建。可以通过访问栈的底层容器来实现遍历,前提是需要了解依赖的具体底层容器类型。
注:可能会因为编译器问题导致出错(不能直接访问它的底层容器(如 c),因为受到了protected访问控制限制),那就参考4.4或者4.5的方法

#include <iostream>
#include <stack>
#include <deque>

using namespace std;

int main() {
    stack<int, deque<int>> s;  // 使用deque作为底层容器
    s.push(10);
    s.push(20);
    s.push(30);

    // 通过底层容器的迭代器进行遍历
    for (auto it = s.c.begin(); it != s.c.end(); ++it) {
        cout << *it << " ";
    }
    return 0;
/*
output:10 20 30 
*/
}

4.4 使用deque来模拟栈,并遍历:

#include <iostream>
#include <deque>

using namespace std;

int main() {
    // 使用 std::deque 模拟栈
    deque<int> deq;
    // 向 "栈" 中推入元素
    deq.push_back(10);
    deq.push_back(20);
    deq.push_back(30);

    // 遍历 deque (从栈底到栈顶)
    for (auto it = deq.begin(); it != deq.end(); ++it) {
        cout << *it << " ";
    }
    cout << endl;

    // 模拟栈顶操作(访问最后一个元素)
    cout << "栈顶元素是: " << deq.back() << endl;

    // 模拟弹出栈顶元素
    deq.pop_back();  // 移除栈顶元素
    cout << "弹出栈顶元素后,新的栈顶是: " << deq.back() << endl;

    return 0;
}
/*
output:
10 20 30 
栈顶元素是: 30
弹出栈顶元素后,新的栈顶是: 20
*/

4.5 自定义栈类

标准库不允许直接访问stack的底层容器,但可以通过继承stack来扩展它并提供对底层容器的访问接口。

#include <iostream>
#include <stack>
#include <deque>

using namespace std;

// 自定义继承 std::stack 的类
template<typename T>
class MyStack : public stack<T> {
public:
    // 提供底层容器的访问接口
    typename deque<T>::iterator begin() {
        return this->c.begin();
    }

    typename deque<T>::iterator end() {
        return this->c.end();
    }
};

int main() {
    // 使用自定义栈
    MyStack<int> s;
    s.push(10);
    s.push(20);
    s.push(30);

    // 遍历底层容器
    cout << "栈中的元素(从底到顶):" << endl;
    for (auto it = s.begin(); it != s.end(); ++it) {
        cout << *it << " ";
    }
    return 0;
}
/*
output:10 20 30 
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值