蓝桥杯基础数据结构-栈

**

什么是栈?

**
思考一下:

为什么链式存储的方式的栈栈顶指针与队列队头的指针相反,是什么原因呢?

其实我们知道链表的表头是用来插入数据的,表头处的数据才是最后插入的,先入后出原则,所以表头处的数据最先出栈,也就是栈的顶啦!听到这里,有人迷糊了,什么头什么尾的,队列跟栈傻傻分不清… 链表是数据存储的组织方式,他只是决定了数据在内存中怎么存储,而栈和队列是说我们是按照什么方式存储。栈可以理解为整理衣服,先放进箱子里的,要想拿出来得把后放进箱子里的衣服先拿出来。而链表或顺序表是说,我究竟是放进了箱子还是放进了衣柜还是放进了异度空间。
栈既可以用链表来表示,也可以用顺序表来表示。
栈的逻辑结构:
栈:只允许在一端进行插入、删除操作的线性表。
空栈:不含任何数据元素的栈。
允许插入(也称进栈、压栈、入栈)、删除(也称出栈)的一端称为栈顶。
时间复杂度

isEmpty() 查找操作时间复杂度为 O(1)
in() 入队操作时间复杂度为 O(1)
out() 出队操作时间复杂度为 O(1)

对于一个栈,1.先创建一个栈以及栈顶指针;2.声明并定义入栈函数和出栈函数;3.声明并定义判空函数,通过栈顶指针大小来判断;4.声明定义取栈顶函数(首先需要判断是否为空)。当然如果使用C++、JAVA这些语言栈都是定义好的,省去了我们创建进站、出栈、去栈顶函数的创建了。
在这里插入图片描述

对于C++:
在 C++ 的 stack 模板定义了如下操作:

top():

返回一个栈顶元素的引用,类型为 T&。如果栈为空,返回值未定义。

push(const T& obj):

可以将对象副本压入栈顶。这是通过调用底层容器的 push_back() 函数完成的。

push(T&& obj):

以移动对象的方式将对象压入栈顶。这是通过调用底层容器的有右值引用参数的 push_back() 函数完成的。

pop():

弹出栈顶元素。

size():

返回栈中元素的个数。
第一步:
引入模板类,并定义声明一个栈类

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

我们声明并定义取栈顶函数:

只需要将栈顶元素取出即可
先判断是否为空
#include <iostream>
#include <stack>
using namespace std;

stack<string> myStack;

int main ()
{
    int N;
    cin>>N;
    for(int i=0;i<N;i++)
    {
        string op,name;
        cin>>op>>name;
        if(op=="in") myStack.push(name);
        else {
            while(myStack.top()!=name){
                myStack.pop();
            }
            myStack.pop();
        }
    }
    if(myStack.empty()) cout<<"Empty"<<endl;
    else cout<<myStack.top()<<endl;
}

JAVA代码:
Java 的内置栈类
我们先看一下 Java 中栈的定义及相应的函数.

栈是 Vector 的一个子类,它实现了一个标准的后进先出的栈,至于什么是 Vector,大家可以理解为能力超强的数组,在后面的课程中,我们会进行讲解。
堆栈定义了默认构造函数,用来创建一个空栈。
大家可能理解起来有困难,不必担心,咱们现阶段知道如何定义,并且如何调用函数后,之后在不断的实践中,就会慢慢理解了。

在 Java 的 stack 模板定义了如下操作流程:

push():

执行 push 时(即,将元素推入栈中),是通过将元素追加的数组的末尾中。

peek():

执行 peek 时(即,取出栈顶元素,不执行删除),是返回数组末尾的元素。

pop():

执行 pop 时(即,取出栈顶元素,并将该元素从栈中删除),是取出数组末尾的元素,然后将该元素从数组中删除。

empty():

继承于 Vector,返回是否为空

size():

继承 Vector,返回元素的个数。
引入模板类,并定义声明一个栈类:

import java.util.Scanner;
import java.util.Stack;

public class Main {

    static Stack Mystack =new Stack();
}

主函数代码:

public static void main(String[] args)
{
    int N;
    Scanner in=new Scanner(System.in);
    N=in.nextInt();
    for(int i=0;i<N;i++)
    {
        String op,name;
       op=in.next();
       name=in.next();
       // System.out.println(op+"  "+name);
        if(op.contains("in") )
            Mystack.push(name);

        else {
            while(!Mystack.peek().equals(name)){
               // System.out.println(getTop());
                Mystack.pop();
            }
            Mystack.pop();
        }
    }
    if(Mystack.empty()) System.out.println("Empty");
    else System.out.println(Mystack.peek());
}

例题:小邋遢的衣橱
小邋遢 MS.Jinlin 是个爱打扮的公主,他有很多晚礼服如"LALA" “NIHAOMA”、“WOBUHAO”、"NIHAOBUHAO"等众多衣服,可是由于衣服太多他要把它们装进箱子,但是作为公主,肯定是会突发奇想觉得哪件衣服好看,就把他拿了出来,当然那件衣服上面的衣服也被拿出来了,而且会弄乱了,小邋遢在经过几次的叠衣服和取衣服后,他想知道箱子里最上面的衣服是哪一件,如果箱子为空的话,就告诉她 Empty ,如果有多件一样的衣服,肯定是取走最上面的那一件啦。
输入:

第 1 行,输入N,代表共计进行了几次操作
第 2 行至第 N+1 行,进行in out 操作
in 为 放入衣服
out 为 取出衣服

格式:

 in name1  
    out name2

copy
现在有以下样例输入:

样例 1:

输入:

6
in AMDYES
in INTELNO
in USBAD
in CNYES
out INTELNO
in MDICN

输出:

MDICN

结果:

import java.util.Scanner;
import java.util.Stack;

public class Main {
    public static void main(String[] args) {
         Stack MyStack = new Stack();
         Scanner sc = new Scanner(System.in);
         int n = sc.nextInt();
         for(int i=0;i<n;i++){
             String inout,name;
             inout = sc.next();
             name = sc.next();
             if(inout.contains("in")){
                 MyStack.push(name);
             }else{
                 while(!MyStack.peek().equals(name)){
                     MyStack.pop();
                 }
                 MyStack.pop();
             }
         }
         if(MyStack.empty()){
             System.out.println("Empty");
         }else{
             System.out.println(MyStack.peek());
         }
    }
}

其中用到了一个判断字符识别的语句,一直没有运行正确:

if(inout.contains("in")){
                 MyStack.push(name);
             }

下面语句中取出栈顶元素并和name比较,如果不相同就一直删除栈顶元素,直到找到name并取出。使用while循环来实现操作。

if(inout.contains("in")){
                 MyStack.push(name);
             }else{
                 while(!MyStack.peek().equals(name)){
                     MyStack.pop();
                 }
                 MyStack.pop();
             }
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值