首页 > 其他分享 >3.2.栈

3.2.栈

时间:2025-01-11 12:58:35浏览次数:7  
标签:back pop stk num 3.2 push stack

栈是一个带有限制的表,它的插入和删除都只能在一个位置上进行,即只能在表的末端进行,这个末端叫栈顶(top)

栈模型

栈也叫LIFO(后进先出)表。正如其名,栈的特点就是在最后入栈的元素反而最早出栈。对于栈,我们基本上就只有两种操作,一种是进栈(push),一种是出栈(pop),前者就是插入元素,后者就是删除栈顶的元素。对于一个栈,我们能操作的只有栈顶。

请添加图片描述

如上图所示,目前只能操作"5"这个元素,要么在它后面push,要么把它pop。

栈的实现

栈只是一个ADT,具体实现还是要靠实现表的方法。其中listvector都可以实现它

list实现栈

使用单链表就可以实现栈的操作,我们可以通过在表的前端插入来实现push操作,通过删除表前端元素来实现pop操作

#include <iostream>
#include <list>

// 自定义栈类
class MyStack {
private:
    std::list<int> data; // 使用list来存储栈元素

public:
    // 入栈操作
    void push(int value) {
        data.push_back(value);
    }

    // 出栈操作
    void pop() {
        if (!empty()) {
            data.pop_back();
        }
    }

    // 获取栈顶元素
    int top() {
        if (!empty()) {
            return data.back();
        }
        // 这里可以根据实际需求抛出异常或返回一个特定值表示栈为空
        return -1; 
    }

    // 判断栈是否为空
    bool empty() {
        return data.empty();
    }
};

int main() {
    MyStack stack;
    stack.push(1);
    stack.push(2);
    stack.push(3);

    std::cout << "栈顶元素: " << stack.top() << std::endl;

    stack.pop();
    std::cout << "出栈后栈顶元素: " << stack.top() << std::endl;

    return 0;
}

上述代码自定义了一个MyStack栈结构,内部使用的是list数据类型来存储栈中的元素。定义了四种操作,分别是入栈,出栈,获取栈顶元素,判断是否为空栈。下面的main函数中对上面定义的结构进行了测试。

vector实现栈

vector实现栈很明显是一个更明智的操作,因为我们在前面讲到过,list用链表存储元素的缺点就是随机读取性能很弱,而vector采用在内存中连续存储的方式,而且自带的push_backpop_back方法,实现栈来说更简单。

#include <iostream>
#include <vector>

class Stack {
private:
    std::vector<int> data; // 使用vector存储栈元素

public:
    // 入栈操作
    void push(int value) {
        data.push_back(value);
    }

    // 出栈操作
    void pop() {
        if (!empty()) {
            data.pop_back();
        }
    }

    // 获取栈顶元素
    int top() {
        if (!empty()) {
            return data.back();
        }
        // 可根据实际情况处理栈为空的情况,这里简单返回-1
        return -1; 
    }

    // 判断栈是否为空
    bool empty() {
        return data.empty();
    }
};

int main() {
    Stack stack;
    stack.push(1);
    stack.push(2);
    stack.push(3);

    std::cout << "栈顶元素: " << stack.top() << std::endl;

    stack.pop();
    std::cout << "出栈后栈顶元素: " << stack.top() << std::endl;

    return 0;
}

同样也是实现四个基本功能,入栈、出栈、获取栈顶元素和判断是否为空

栈的应用

下面用一个题目来讲解一下栈的应用(洛谷-P1981)

请添加图片描述

这个题目要求输入一个计算式,只包含数字和"+""*"两种符号,最后输出结果。

这道题毫无疑问得用栈的知识,先把输入的数字压入栈,然后根据它后面的符号再对栈顶进行对应的操作,如果是"*"号,就对栈顶和输入的数字做相乘处理,再把结果压入栈,如果是"+"号就直接压入栈,最后栈中的数字全都是相加处理,直接全部相加得到结果。

分析输入,我们可以发现除掉第一个数字,后面的形式全部都是一个符号加一个数字,那么我们可以选择先将第一个数字压入栈,再循环输入后面的内容,进行对应的操作

cin >> first_num;
    first_num %= 10000;
    stk.push_back(first_num);
    while (cin >> sig >> num) {
        if (sig == '*') {
            first_num = stk.back() * (num % 10000) % 10000;
            stk.pop_back();
            stk.push_back(first_num);
        }
        else if (sig == '+') {
            stk.push_back(num % 10000);
        }
    }

接着就是把栈中的所有数字依次出栈相加得到结果了,循环判断条件就是数组不是空时。

int sum = 0;
    while (!stk.empty()) {
        sum += stk.back();
        sum %= 10000;
        stk.pop_back();
    }
    cout << sum << endl;

完整代码如下:

#include <iostream>
#include <vector>

using namespace std;

vector<int> stk;

int main() {
    int first_num, num;
    char sig;
    cin >> first_num;
    first_num %= 10000;
    stk.push_back(first_num);
    while (cin >> sig >> num) {
        if (sig == '*') {
            first_num = stk.back() * (num % 10000) % 10000;
            stk.pop_back();
            stk.push_back(first_num);
        }
        else if (sig == '+') {
            stk.push_back(num % 10000);
        }
    }
    int sum = 0;
    while (!stk.empty()) {
        sum += stk.back();
        sum %= 10000;
        stk.pop_back();
    }
    cout << sum << endl;
    return 0;
}

那么以上是我们用vector模拟栈,其实c++中的STL库中有栈(stack)这个数据结构,我们可以像引用vector一样直接导入引用它,下面我们一起来看看如何导入并引用栈吧

STL中的stack栈

以下是C++ STL库中栈(stack)的常见用法:

  1. 包含头文件 首先需要包含stack头文件:
#include <stack>
  1. 创建栈对象 可以创建一个存储特定类型元素的栈,例如存储int类型元素的栈:
std::stack<int> myStack; 
  1. 基本操作
  • 入栈(push):将元素添加到栈顶。
myStack.push(10); 
myStack.push(20); 
  • 出栈(pop):移除栈顶元素。
myStack.pop();
  • 获取栈顶元素(top):获取栈顶元素的值,但不移除它。
int topElement = myStack.top();
  • 判断栈是否为空(empty):检查栈是否为空,返回true表示空,false表示非空。
if (myStack.empty()) {
    std::cout << "栈为空" << std::endl; } 
else {
    std::cout << "栈不为空" << std::endl; }
  • 获取栈的大小(size):返回栈中元素的数量。
std::cout << "栈的大小为:" << myStack.size() << std::endl;

以下是一个完整的示例,演示了栈的基本操作:

#include <iostream>
#include <stack>

int main() {
    std::stack<int> myStack;

    myStack.push(5);
    myStack.push(15);
    myStack.push(25);

    std::cout << "栈顶元素:" << myStack.top() << std::endl;

    myStack.pop();

    std::cout << "出栈后栈顶元素:" << myStack.top() << std::endl;

    std::cout << "栈是否为空:" << (myStack.empty()? "是" : "否") << std::endl;

    std::cout << "栈的大小:" << myStack.size() << std::endl;

    return 0;
}

感兴趣的话可以试着用stack做一下上面的那个题目。

标签:back,pop,stk,num,3.2,push,stack
From: https://blog.csdn.net/m0_60046831/article/details/145075847

相关文章

  • MobaXterm V23.2 最新专业版激活破解
    MobaXterm是一款远程终端控制软件,它不仅可以像PuTTY一样通过SSH连接RaspberryPi等开源硬件,并且还能:直接的便携版;内建多标签和多终端分屏;内建SFTP文件传输;内建Xserver,可远程运行X窗口程序;直接支持VNC/RDP/Xdmcp等远程桌面;默认的UTF-8编码;更加友好的串口连接设置;便携版操作更明确......
  • 优化永不止步:TinyVue v3.20.0 正式发布,更美观的官网UI,更友好的文档搜索,更强大的主题配
    你好,我是Kagol,个人公众号:前端开源星球。我们非常高兴地宣布,2024年12月4日,TinyVue发布了v3.20.0......
  • 德普微一级代理 DP040N04DTL TO-252 DPMOS N-MOSFET 40V 100A 3.2mΩ
    Features•UsesadvancedTrenchMOSFETtechnology•ExtremelylowRDS(on)/HighSpeedPowerSwitching•ExcellentQgxRDS(on)product(FOM)•QualifiedaccordingtoJEDECcriteriaProductSummaryPart#:DP040N04DTLVDS:40VRDS(on).......
  • Windows10 64环境下用Qt5.12.12自带的mingw730_64构建编译OpenCV4.1.0时cmake-3.20.6
    一、环境条件说明:操作系统:Windows1064环境编译工具:用Qt5.12.12自带的mingw730_64构建构建对象:编译OpenCV4.1.0的Release64位和Debug64位动态链接库构建工具:CMake中的参数配置二、cmake-3.20.6中的参数配置1、按照下图配置好OpenCV4.1.0的源代码目录和构建编译输出目录,然......
  • Amazon Bedrock 实践 - 利用 Llama 3.2 模型分析全球糖尿病趋势
    黄浩文资深开发者布道师亚马逊云科技拥有电信、互联网以及云计算等行业超过20年的丰富经验,曾任职于微软、Sun和中国电信。他目前专注于生成式AI、大型语言模型(LLM)、机器学习和数据科学等领域的技术内容创作和实践分享,致力于赋能全球开发者。本博客内容原文来自于作者......
  • 【Basic Abstract Algebra】Exercises for Section 3.2 — Normal subgroups and fact
    If\(H<G\)and\([G:H]=2\),showthat\(H\triangleleftG\).Proof:If\([G:H]=2\),then\(gH=Hg\)forall\(g\inG\),so\(H\triangleleftG\).【BasicAbstractAlgebra】ExercisesforSection3.1—CosetsandLagrange'sTheorem-只会......
  • 3.2 图像加权和
    OpenCV中提供了函数cv2.addWeighted(),用来实现图像的加权和(混合、融合),该函数的语法格式为:dst=cv2.addWeighted(src1,alpha,src2,beta,gamma)其中,参数alpha和beta是src1和src2所对应的系数,它们的和可以等于1,也可以不等于1。该函数实现的功是dst=src1alpha+src2be......
  • Llama 3.2 900亿参数视觉多模态大模型本地部署及案例展示
    Llama3.2900亿参数视觉多模态大模型本地部署及案例展示本文将介绍如何在本地部署Llama3.290B(900亿参数)视觉多模态大模型,并开发一些UseCase,展示其强大的视觉理解能力。Llama3.2介绍今年9月,Meta公司发布了Llama3.2版本,包括11B和90B的中小型视觉大语言模型,适用于边缘计......
  • 5.3.2 Xenomai3:使用xeno-config获取编译和链接参数
    点击查看系列文章=》 InterruptPipeline系列文章大纲-CSDN博客原创不易,需要大家多多鼓励!您的关注、点赞、收藏就是我的创作动力!5.3.2Xenomai3:使用xeno-config获取编译和链接参数xeno-config是一个辅助脚本,用于为使用Xenomai库的应用程序提供正确的编译和链接标志。通过......
  • 使用Llama-3.2-1B遇到的bug
    背景在使用Llama-3.2-1B时遇到一个关于pad_tokens经验不足的bug。没有指定pad_token的时候分词器会报错,这个使用有以下两种解决策略:配一个新的token。tokenizer.add_special_tokens({'pad_token':'[PAD]'})model.resize_token_embeddings(len(tokenizer))#如果添加了新......