学而时习之:C++中的标准模板6

35 阅读3分钟

C++ STL 中的栈(Stack)

stack 栈容器 遵循后进先出(LIFO)的插入和删除顺序。这意味着最近插入的元素最先被移除,而最先插入的元素最后才被移除。这是通过仅在栈的一端(通常称为栈顶)进行元素的插入和删除来实现的。

C++代码如下:

#include <iostream>
#include <stack>
using namespace std;

int main()
{
    stack<int> st;  // 创建一个整数类型的栈
    st.push(10);    // 将元素10压入栈
    st.push(5);     // 将元素5压入栈
    
    // 访问栈顶元素
    cout << "栈顶元素: " << st.top() << endl;
    
    // 弹出一个元素
    st.pop();
    cout << "弹出元素后的栈顶元素: " << st.top() << endl;
    
    return 0;
}

语法

栈在 <stack> 头文件中被定义为 std::stack 类模板。

stack<T> st;

其中:

  • T:栈中元素的数据类型(如 intchar 等)。
  • st:给栈起的名字。

基本操作

以下是可以在栈上执行的基本操作:

1. 插入元素

在栈中,新元素只能通过 push() 方法从栈顶插入。

#include <iostream>
#include <stack>
using namespace std;

int main()
{
    stack<int> st;  // 创建一个整数类型的栈

    // 向栈顶插入元素
    st.push(10);
    st.push(20);
    st.push(30);
    st.push(40);

    return 0;
}

image.png

2. 访问元素

只能使用 top() 方法访问栈顶的元素。

#include <iostream>
#include <stack>
using namespace std;

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

    // 访问栈顶元素
    cout << st.top();
    return 0;
}
40

注意:peek() 仅用于查看栈顶元素,而不会将其输出(打印)。

3. 删除元素

在栈中,只有栈顶元素可以通过 pop() 方法一次操作被删除。

#include <iostream>
#include <stack>
using namespace std;

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

    // 删除栈顶元素
    st.pop();

    while (!st.empty()) {
        cout << st.top() << " ";
        st.pop();
    }
    return 0;
}
30 20 10

image.png

4. empty()

该函数用于检查栈是否为空。如果栈中没有元素,则返回 true;否则返回 false

#include <iostream>
#include <stack>
using namespace std;

int main() {

    stack<int> st;
    if (st.empty()) {
        cout << "栈为空" << endl;
    }
    st.push(100);
    if (!st.empty()) {
        cout << "栈不为空,栈顶元素为:" << st.top() << endl;
    }
    return 0;
}
栈为空
栈不为空,栈顶元素为:100

5. 栈的大小size

size() 函数用于返回栈中当前存储的元素个数。它可以帮助你了解栈中有多少项,而不会修改栈的内容。

#include <iostream>
#include <stack>
using namespace std;

int main()
{
    stack<int> st;
    st.push(10);
    st.push(5);
    cout << "栈的大小: " << st.size() << endl;
    st.pop();
    cout << "栈的大小: " << st.size() << endl;
    return 0;
}
栈的大小: 2
栈的大小: 1

6.伪遍历

由于除栈顶外无法直接访问栈中的其他元素,栈实际上不能被遍历。但我们可以创建一个栈的副本,依次访问并删除该副本的栈顶元素。当副本栈为空时,就完成了一次“不破坏原栈”的遍历。

#include <iostream>
#include <stack>
using namespace std;

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

    // 创建原栈的副本
    stack<int> temp(st);

    while (!temp.empty())
    {
        cout << temp.top() << " ";
        temp.pop();
    }
    return 0;
}
40 30 20 10

解释:上述程序通过复制原栈 st 得到副本 temp,避免修改原栈。while 循环不断用 top() 打印并用 pop() 删除 temp 的栈顶,直到栈空,从而实现伪遍历。

时间复杂度
下表列出栈各操作的时间复杂度:

操作时间复杂度
插入元素(push)O(1)
删除元素(pop)O(1)
访问栈顶(peek)O(1)
遍历栈O(n)