栈结构的总结

竞赛/基础

栈是什么?

栈(Stack) 是一种 先进后出(FILO) 的线性数据结构,类似于叠盘子:最后放上去的盘子会被最先取走。
核心特性:只能在一端(栈顶)进行插入(入栈)和删除(出栈)操作

  • 基本操作
    • push():元素入栈,放到栈顶。
    • pop():栈顶元素出栈。
    • peek():查看栈顶元素(不删除)。
    • isEmpty():判断栈是否为空。
    • 时间复杂度:所有操作均为 O(1) [[1,3]]。

就像一摞叠在一起的盘子️,有两大特点:

  1. 后进先出:最后放上去的盘子,总是第一个被拿走
  2. 只能操作顶部:拿/放盘子只能从最上面操作

栈的四大应用

应用场景 生活比喻 小例子
撤销功能 写错字时的橡皮擦 按 Ctrl+Z 撤销操作
浏览器后退 参观博物馆的返程路线 点击←返回上一网页
括号匹配 乐高积木的拼插顺序 (({[]})) 是否合法
迷宫路径 面包屑寻路法 用栈记录走过的路线

数组实现栈(手撕栈结构)

#include <iostream>
using namespace std;

int stack[100]; // 栈数组,最大容量为100
int top = -1;   // 栈顶指针,初始化为-1表示栈为空

// 压栈操作
void push(int x) {
    if (top >= 99) {
        cout << "⚠️ 栈满啦!不能再放啦~" << endl;
        return;
    }
    stack[++top] = x; // 先上移栈顶指针,再放入元素
}

// 弹栈操作
int pop() {
    if (top < 0) {
        cout << "⚠️ 栈空啦!没有东西能拿~" << endl;
        return 0;
    }
    return stack[top--]; // 先取出元素,再下移栈顶指针
}

// 查看栈顶元素
int peek() {
    if (top < 0) {
        cout << "⚠️ 栈空啦!没有东西能看~" << endl;
        return 0;
    }
    return stack[top];
}

int main() {
    push(10); // 放入10
    push(20); // 放入20
    push(30); // 放入30

    cout << "栈顶元素: " << peek() << endl; // 查看栈顶元素,输出30

    cout << "弹出元素: " << pop() << endl; // 弹出30
    cout << "弹出元素: " << pop() << endl; // 弹出20

    cout << "栈是否为空: " << (top < 0) << endl; // 判断栈是否为空,输出0(false)

    push(40); // 放入40
    push(50); // 放入50
    push(60); // 放入60,如果栈已满,输出警告信息

    return 0;
}

  • 空栈条件top == -1 [[12]]。
  • 满栈条件top == capacity - 1 [[12, 19]]

操作演示

栈顶元素: 30
弹出元素: 30
弹出元素: 20
栈是否为空: 0

注意事项

  1. 栈溢出:数组大小固定,需提前预判容量,避免 push 时栈满 [[10, 12]]。
  2. 空栈处理pop 或 peek 前检查 isEmpty(),防止越界错误 [[19]]。
  3. 应用选择:根据问题特性选择数组或链表实现,例如需要动态扩容时用链栈 [[6, 15]]。

C++系统自带的栈使用

  1. 包含头文件
    要使用栈,首先需要包含 stack 头文件。

    #include <stack>
    
  2. 创建栈对象
    你可以创建一个栈对象,指定存储元素的类型。如果不指定,则默认为 int 类型。

    std::stack<int> mystack;
    
  3. 基本操作

    • push():向栈中添加元素。
    • pop():移除栈顶元素。
    • top():获取栈顶元素的引用,不移除它。
    • empty():检查栈是否为空。
    • size():返回栈中元素的数量。
    // 向栈中添加元素
    mystack.push(10);
    mystack.push(20);
    mystack.push(30);
    
    // 获取栈顶元素
    int topElement = mystack.top(); // topElement 现在是 30
    
    // 移除栈顶元素
    mystack.pop();
    
    // 再次获取栈顶元素
    topElement = mystack.top(); // topElement 现在是 20
    
    // 检查栈是否为空
    bool isEmpty = mystack.empty(); // isEmpty 是 false
    
    // 获取栈的大小
    size_t stackSize = mystack.size(); // stackSize 是 2
    
  4. 示例代码
    下面是一个使用 C++ STL stack 的完整示例代码。

    #include <iostream>
    #include <stack>
    using namespace std;
    
    int main() {
        stack<int> mystack;
    
        // 向栈中添加元素
        mystack.push(10);
        mystack.push(20);
        mystack.push(30);
    
        // 输出栈顶元素并移除
        while (!mystack.empty()) {
            cout << "弹出元素: " << mystack.top() << endl;
            mystack.pop();
        }
        // 检查栈是否为空
        cout << "栈是否为空: " << (mystack.empty() ? 1 : 0) << endl;
        return 0;
    }
    

这段代码使用了 C++ 的 `stack` 容器来演示栈的基本操作。下面是代码的详细解释:

1. 包含头文件 `<iostream>` 和 `<stack>`,分别用于输入输出和栈容器。
2. 在 `main()` 函数中定义一个 `stack` 对象 `mystack`,用于存储整数类型的元素。
3. 使用 `push()` 方法向栈中添加三个元素:10、20 和 30。
4. 使用 `while` 循环检查栈是否为空,不为空则输出栈顶元素并移除,直到栈为空。
5. 最后检查栈是否为空,输出结果(非空为1,空为0)。

运行这段代码,输出结果为:

弹出元素: 30
弹出元素: 20
弹出元素: 10
栈是否为空: 1





# 经典例题

###  希蒙的羽毛球筒
https://ac.xiaosaima.com/d/CD01_2404/p/470

```c
#include <iostream>
#include <stack>
#include <vector>
using namespace std;

int main() {
    int n;
    cin >> n;
    vector<int> balls(n);
    for (int i = 0; i < n; ++i) {
        cin >> balls[i];
    }

    stack<int> s; // 使用 stack 模拟球筒
    vector<int> result; // 存储取球的顺序

    for (int ball : balls) {
        if (s.empty() || ball <= s.top()) {
            s.push(ball); // 可以放入球筒
        }
    }

    // 输出取球序列
    while (!s.empty()) {
        result.push_back(s.top());
        s.pop();
    }

    // 输出结果
    for (int i = result.size() - 1; i >= 0; --i) {
        if (i == 0) {
            cout << result[i];
        } else {
            cout << result[i] << " ";
        }
    }

    return 0;
}

括弧匹配检验(栈)

https://ac.xiaosaima.com/d/CD01_2404/p/459

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

int main() {
    string s;
    cin >> s;
    stack<char> st;

    for (char c : s) {
        if (c == '(' || c == '[') {
            st.push(c); // 左括号入栈
        } else if (c == ')' || c == ']') {
            if (st.empty()) {
                cout << "Wrong" << endl;
                return 0;
            }
            char top = st.top();
            st.pop();
            if ((c == ')' && top != '(') || (c == ']' && top != '[')) {
                cout << "Wrong" << endl;
                return 0;
            }
        }
    }

    if (st.empty()) {
        cout << "OK" << endl;
    } else {
        cout << "Wrong" << endl;
    }

    return 0;
}
posted @ 2025-11-23 17:22  stephen_zuo  阅读(14)  评论(0)    收藏  举报