Stack简介

简介: 在C++的标准模板库(STL)中,Stack(栈)是一种常用的容器,它遵循后进先出(LIFO)的原则,即最后进入栈的元素最先被移出栈。Stack提供了一种简单而高效的方式来管理数据,是处理后进先出数据流的理想选择。

特性:

  • 后进先出(LIFO):Stack容器遵循后进先出的原则,保证了数据按照插入顺序的相反顺序被处理。
  • 简单易用:Stack提供了简单的接口和操作方法,使得使用起来非常便捷。
  • 基于其他容器实现:Stack的底层实现通常基于deque或vector容器,保证了高效的插入和删除操作。

优缺点:

  • 优点:

    • 高效的插入和删除操作:Stack的插入和删除操作都是在栈顶进行,时间复杂度为常数时间。
    • 线程安全:Stack在多线程环境下使用时,可以通过加锁等机制保证线程安全。
    • 适用于各种后进先出场景:Stack适用于处理各种后进先出的数据流,如函数调用栈、表达式求值等。
  • 缺点:

    • 不支持随机访问:Stack不支持随机访问元素,只能在栈顶进行插入和删除操作。
    • 不支持迭代器:Stack不支持迭代器,无法对栈中的元素进行遍历。

使用方法: 使用Stack容器非常简单,只需要包含头文件<stack>,然后通过创建Stack对象并调用其成员函数来进行操作。以下是一些常见的操作方法:

成员函数:

  • 构造函数:用于创建一个空的栈。
  • push():将元素压入栈顶。
  • pop():将栈顶元素弹出栈。
  • top():返回栈顶元素。
  • empty():检查栈是否为空。
  • size():返回栈中元素的个数。

适用场景:

  • 函数调用栈:适用于需要按照函数调用顺序进行操作的场景,如递归算法、深度优先搜索等。
  • 表达式求值:适用于需要按照表达式结构进行操作的场景,如中缀表达式转换为后缀表达式等。
  • 堆栈操作:适用于需要按照堆栈数据结构进行操作的场景,如处理括号匹配、回文串判断等。

基本操作示例:

#include <iostream>
#include <stack>
#include <algorithm>
#include <numeric>
#include<vector>

int main() {
    // 创建一个空栈
    std::stack<int> myStack;

    // 入栈操作
    myStack.push(5);
    myStack.push(10);
    myStack.push(15);

    // 使用循环遍历栈并打印元素
    std::cout << "Stack elements: ";
    std::stack<int> tempStack = myStack; // 复制一份栈
    while (!tempStack.empty()) {
        std::cout << tempStack.top() << " ";
        tempStack.pop();
    }
    // 获取栈的大小并打印
    std::cout << "Stack size: " << myStack.size() << std::endl;

    // 判断栈是否为空
    if (!myStack.empty()) {
        // 访问栈顶元素并打印
        std::cout << "Top element: " << myStack.top() << std::endl;

        // 出栈操作
        myStack.pop();
        std::cout << "Popped top element" << std::endl;
    }


    std::cout << std::endl;

    /// 使用排序算法对栈中的元素进行排序
    std::vector<int> sortedVec;
    while (!myStack.empty()) {
        sortedVec.push_back(myStack.top());
        myStack.pop();
    }
    std::sort(sortedVec.begin(), sortedVec.end());

    // 使用循环遍历排序后的向量并将元素依次入栈
    for (int i = sortedVec.size() - 1; i >= 0; --i) {
        myStack.push(sortedVec[i]);
    }

    // 使用循环遍历栈并打印排序后的元素
    std::cout << "Sorted stack elements: ";
    std::stack<int> anotherStack = myStack; // 复制一份栈
    while (!anotherStack.empty()) {
        std::cout << anotherStack.top() << " ";
        anotherStack.pop();
    }
    std::cout << std::endl;

    // 查找最大/最小元素
    int maxElement = sortedVec.back();
    int minElement = sortedVec.front();

    std::cout << "Max element in stack: " << maxElement << std::endl;
    std::cout << "Min element in stack: " << minElement << std::endl;

    return 0;

}

函数调用栈示例:

#include <iostream>
#include <stack>

//函数调用栈的示例
void func3() {
    std::cout << "Inside func3" << std::endl;
}

void func2() {
    std::cout << "Inside func2, calling func3" << std::endl;
  
}

void func1() {
    std::cout << "Inside func1, calling func2" << std::endl;
   
}

int main() {
    std::stack<void(*)()> callStack; // 使用函数指针作为栈元素类型

    // 将所有函数指针存入栈中
    callStack.push(func1);
    callStack.push(func2);
    callStack.push(func3);

    // 依次调用栈中的函数
    while (!callStack.empty()) {
        // 取出栈顶函数指针
        void (*currentFunc)() = callStack.top();
        callStack.pop();

        // 调用函数
        currentFunc();
    }

    return 0;
}

表达式求值示例:

#include <iostream>
#include <stack>
#include <string>

//栈用来求表达式的值
// 函数用于计算后缀表达式的值
int evaluatePostfix(const std::string& expression) {
    std::stack<int> operandStack; // 创建一个整数类型的栈用于存储操作数

    // 遍历后缀表达式中的每个字符
    for (char c : expression) {
        if (std::isdigit(c)) { // 如果是数字字符,则将其转换为整数并压入栈中
            operandStack.push(c - '0');
        }
        else if (c == '+') { // 如果是加号运算符,则从栈中弹出两个操作数相加,并将结果压入栈中
            int operand2 = operandStack.top();
            operandStack.pop();
            int operand1 = operandStack.top();
            operandStack.pop();
            operandStack.push(operand1 + operand2);
        }
    }

    // 返回栈顶元素,即为后缀表达式的值
    return operandStack.top();
}

int main() {
    std::string postfixExpression = "33+"; // 后缀表达式表示 3+3

    std::cout << "Postfix Expression: " << postfixExpression << std::endl;
    std::cout << "Result: " << evaluatePostfix(postfixExpression) << std::endl;

    return 0;
}

堆栈操作:处理括号匹配、回文串判断示例:

#include <iostream>
#include <stack>
#include <string>

bool isMatchingParentheses(const std::string& expression) {
    std::stack<char> parenthesesStack;

    for (char ch : expression) {
        if (ch == '(' || ch == '[' || ch == '{') {
            parenthesesStack.push(ch);
        }
        else if (ch == ')' || ch == ']' || ch == '}') {
            if (parenthesesStack.empty()) {
                return false; // 括号不匹配,右括号多余
            }
            char top = parenthesesStack.top();
            parenthesesStack.pop();
            if ((ch == ')' && top != '(') || (ch == ']' && top != '[') || (ch == '}' && top != '{')) {
                return false; // 括号不匹配,右括号与栈顶左括号不匹配
            }
        }
    }

    return parenthesesStack.empty(); // 括号匹配,堆栈应为空
}

// 判断字符串是否为回文串的函数
bool isPalindrome(const std::string& str) {
    std::stack<char> charStack; // 创建一个字符栈

    // 将字符串的字符依次压入栈中
    for (char ch : str) {
        charStack.push(ch);
    }

    // 逐个比较栈顶字符与字符串的字符
    for (char ch : str) {
        if (ch != charStack.top()) {
            return false; // 如果有不相等的字符,则不是回文串
        }
        charStack.pop(); // 比较完毕后,弹出栈顶字符
    }

    return true; // 如果所有字符都匹配,则是回文串
}


int main() {
    std::string expression1 = "(a+b)*[c-d]/{e+f}";
    std::string expression2 = "((a+b)*[c-d]/{e+f}";
    // 测试用例1:回文串
    std::string str1 = "racecar";
    // 测试用例2:非回文串
    std::string str2 = "hello";

    if (isMatchingParentheses(expression1)) {
        std::cout << "表达式 1 有匹配的括号。" << std::endl;
    }
    else {
        std::cout << "表达式 1 没有匹配的括号。" << std::endl;
    }

    if (isMatchingParentheses(expression2)) {
        std::cout << "表达式 2 有匹配的括号。" << std::endl;
    }
    else {
        std::cout << "表达式 2 没有匹配的括号。" << std::endl;
    }

    // 判断字符串1是否为回文串,并输出结果
    if (isPalindrome(str1)) {
        std::cout << str1 << " 是回文串。" << std::endl;
    }
    else {
        std::cout << str1 << " 不是回文串。" << std::endl;
    }

    // 判断字符串2是否为回文串,并输出结果
    if (isPalindrome(str2)) {
        std::cout << str2 << " 是回文串。" << std::endl;
    }
    else {
        std::cout << str2 << " 不是回文串。" << std::endl;
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值