探索C++中的数据结构:栈(Stack)的奥秘

引言

栈是计算机科学中最基础且重要的数据结构之一,它像一摞盘子一样遵循"后进先出"(LIFO)的原则。无论是函数调用、表达式求值,还是浏览器前进后退功能,栈都扮演着关键角色。本文将深入解析栈的C++实现及其应用场景。


一、栈的核心概念

1.1 什么是栈?

  • 定义:只能在一端(栈顶)进行插入(push)和删除(pop)操作的线性表

  • 特点:

    • 后进先出(Last In First Out)

    • 时间复杂度均为O(1)的基本操作

    • 大小可固定(数组实现)或动态(链表实现)

1.2 基本操作

操作 功能描述
push() 元素入栈
pop() 栈顶元素出栈
top() 查看栈顶元素
empty() 判断栈是否为空
size() 返回栈中元素数量

二、C++实现栈

2.1 数组实现(固定大小)

cpp 复制代码
template <typename T, int MAX_SIZE = 100>
class ArrayStack {
private:
    T data[MAX_SIZE];
    int topIndex = -1;

public:
    void push(T value) {
        if (topIndex >= MAX_SIZE-1)
            throw std::overflow_error("Stack overflow");
        data[++topIndex] = value;
    }

    T pop() {
        if (empty())
            throw std::underflow_error("Stack underflow");
        return data[topIndex--];
    }

    T top() const {
        if (empty())
            throw std::runtime_error("Stack is empty");
        return data[topIndex];
    }

    bool empty() const { return topIndex == -1; }
    int size() const { return topIndex + 1; }
};

2.2 链表实现(动态大小)

cpp 复制代码
template <typename T>
class LinkedListStack {
private:
    struct Node {
        T data;
        Node* next;
        Node(T val) : data(val), next(nullptr) {}
    };
    
    Node* topNode = nullptr;
    int count = 0;

public:
    void push(T value) {
        Node* newNode = new Node(value);
        newNode->next = topNode;
        topNode = newNode;
        count++;
    }

    T pop() {
        if (empty())
            throw std::underflow_error("Stack underflow");
        
        Node* temp = topNode;
        T val = temp->data;
        topNode = topNode->next;
        delete temp;
        count--;
        return val;
    }

    // ...其他方法实现类似数组版本
};

三、栈的典型应用

3.1 括号匹配检测

cpp 复制代码
bool isBalanced(const string& expr) {
    stack<char> s;
    for (char c : expr) {
        if (c == '(' || c == '[' || c == '{') {
            s.push(c);
        } else {
            if (s.empty()) return false;
            char top = s.top();
            if ((c == ')' && top != '(') ||
                (c == ']' && top != '[') ||
                (c == '}' && top != '{'))
                return false;
            s.pop();
        }
    }
    return s.empty();
}

3.2 其他常见应用场景

  1. 函数调用栈

  2. 表达式求值(逆波兰表达式)

  3. 浏览器历史记录

  4. 撤销(Undo)操作

  5. 迷宫路径查找


四、STL中的stack容器

C++标准库提供了现成的stack模板:

cpp 复制代码
#include <stack>

stack<int> s;
s.push(10);
s.pop();

// 重要方法:
// empty(), size(), top(), push(), pop()

五、栈的复杂度分析

操作 时间复杂度 空间复杂度
push() O(1) O(n)
pop() O(1) O(n)
top() O(1) O(1)
empty() O(1) O(1)

结语

栈作为一种基础数据结构,其简洁性和高效性使其成为算法设计中的重要工具。理解栈的底层实现有助于开发者更好地利用这一数据结构解决实际问题。建议读者尝试实现自己的栈类,并通过LeetCode等平台上的相关题目(如:20.有效的括号、155.最小栈)来巩固学习成果。

相关推荐
知识分享小能手33 分钟前
C++ 学习教程,从入门到精通,C++类继承 — 完整知识点详解(13)
开发语言·c++·学习
YYRAN_ZZU34 分钟前
如何编一个gcc的交叉工具链
linux·c++
弹简特37 分钟前
【Java项目-企悦抽】15-活动管理模块02-活动创建测试与活动列表实现
java·开发语言·springboot
斯内普吖38 分钟前
(开源)水果蔬菜商城实战指南 基于 Java + SSM + Vue + MySQL
java·vue.js·mysql·开源
wang_shu_mo_ran1 小时前
Spring IoC和DI概念篇
java·后端·spring
Frank_refuel1 小时前
【C++】手撕JRpc框架(梳理RPC流程)
c++
小狼154541 小时前
拼多多订单数据导出 CSV 实战:接口分页、字段平铺与 5 个数据坑,多多开票助手
java·前端·javascript
Joe_Wang51 小时前
【从0到1学习JVM · 25】同样都要停顿所有线程,Parallel比Serial到底强在哪
java·jvm·学习·垃圾回收
wuminyu1 小时前
JVM虚拟线程的底层实现原理分析
java·linux·c语言·jvm·c++
keyipatience1 小时前
跳表详细解析
开发语言·数据结构·c++·算法·跳表