数据结构 -- 栈(Stack)

一、栈的简介

定义

  栈(英语:stack)又称为堆栈或堆叠,栈作为一种数据结构,它按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。

  由于堆叠数据结构只允许在一端进行操作,因而按照后进先出(LIFO == Last In First Out)的原理运作。栈也称为后进先出

栈的应用场景

  undo操作(撤销)

    例如:将操作的每组数据存入栈中,如果想要撤销,只需要弹出栈顶元素,就可以恢复上一步操作了。

  程序调用的系统栈

    例如:A方法调用B方法得到返回值,B调用C得到返回值,A操作走到了B方法,这个时候可以将A的代码位置存储到栈中,然后走到B方法,B操作走到了C方法,这个时候可以将B的代码位置存储到栈中。最后C执行完成,根据栈的结构开始弹出数据,一步一步再走回A方法。

  判断括号是否有效。下文会有代码实现(详细规则描述可以参考leetcode第20题)

    开括号必须用同一类型的括号闭合。

    开方括号必须按正确顺序闭合。

    例如:正确的:{[()]} {()} 等 。错误的:[{(})] [}{()] 等。

  自定义栈基类的代码实现

    栈在java.util有一个工具类,先不用,自定义实现一个

二、自定义栈-代码

1. 创建一个接口,统一规范栈的实现

public interface Stack<E>{
      // 向栈插入元素
      public void push(E e);

      //取出最上面的元素,并且返回
      public E pop();

      //获取栈的大小
      public int getSize();

      //判断栈是否为空
      public boolean isEmpty();

      //获取栈最上面的元素
      public E peek();
}

2. 基于数组实现栈

import com.wj.queue.ArrayUtil;
//数组实现栈
public class ArrayStack<E> implements Stack<E> {

    private Array<E> array; //Array:https://www.cnblogs.com/FondWang/p/11806545.html

    public ArrayStack(int capacity){
        array = new ArrayUtil<>(capacity);
    }

    public ArrayStack(){
        array = new Array<E>();
    }
    @Override
    public int getSize() {
        return array.getSize();
    }

    @Override
    public boolean isEmpty() {
        return array.isEmpty();
    }

    @Override
    public void push(E o) {
        array.addFirst(o);
    }

    @Override
    public E pop() {
        return array.removeFirst();
    }

    @Override
    public E peek() {
        return array.getFirst();
    }

    @Override
    public String toString() {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("Stack: ");
        stringBuilder.append(‘[‘);
        for (int i = 0; i<array.getSize(); i++){
            stringBuilder.append(array.get(i));
            if (i != array.getSize()-1){
                stringBuilder.append(",");
            }
        }
        stringBuilder.append("] top");
        return stringBuilder.toString();
    }
}

测试代码

public class StackTest {
  public static void main(String[] args) {      ArrayStack<Integer> arrayStack = new ArrayStack();      for (int i=0; i< 10; i++){          arrayStack.push(i);          System.out.println(arrayStack);      }      Integer pop = arrayStack.pop();      System.out.println("移除的内容是:" + pop);      System.out.println("移除后的arrayStack: " + arrayStack);  }}
//测试结果
Stack: [0] top
Stack: [1,0] top
Stack: [2,1,0] top
Stack: [3,2,1,0] top
Stack: [4,3,2,1,0] top
Stack: [5,4,3,2,1,0] top
Stack: [6,5,4,3,2,1,0] top
Stack: [7,6,5,4,3,2,1,0] top
Stack: [8,7,6,5,4,3,2,1,0] top
Stack: [9,8,7,6,5,4,3,2,1,0] top
移除的内容是:9
移除后的arrayStack: Stack: [8,7,6,5,4,3,2,1,0] top

相关栈的应用代码

leetCode第20题,花括号正确闭合

思路:

  • 根据栈的数据结构特点,我们可以先将所有左括号‘[{(’放进栈中,然后判断当前字符如果是‘)]}’这种的右括号,但是栈顶的括号却不匹配,返回false
  • 注意控制判断
  • 这里使用java自带的栈工具类来实现

代码实现:

public class Solution {
    public static void main(String[] args) {
        Solution solution = new Solution();
        System.out.println(solution.isValid("{[]()}"));
    }
    public boolean isValid(String s) {
        Stack<Character> characters = new Stack<>();
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (c == ‘{‘ || c == ‘[‘ || c == ‘(‘) {
                characters.push(c);
            } else {
                if(characters.isEmpty()){
                    return false;
                }
                Character peek = characters.pop();
                switch (c) {
                    case ‘}‘:
                        if (!peek.equals(‘{‘)) {
                            return false;
                        }
                        continue;
                    case ‘]‘:
                        if (!peek.equals(‘[‘)) {
                            return false;
                        }
                        continue;
                    case ‘)‘:
                        if (!peek.equals(‘(‘)) {
                            return false;
                        }
                        continue;
                }
            }
        }
        return characters.isEmpty();
    }}
//测试结果
true//若输入solution.isValid("{[)}") 返回false


原文地址:https://www.cnblogs.com/FondWang/p/11809042.html

时间: 2024-08-08 23:57:23

数据结构 -- 栈(Stack)的相关文章

C# 数据结构 栈 Stack

栈和队列是非常重要的两种数据结构,栈和队列也是线性结构,线性表.栈和队列这三种数据结构的数据元素和元素的逻辑关系也相同 差别在于:线性表的操作不受限制,栈和队列操作受限制(遵循一定的原则),因此栈和队列也称为受限制的线性表. 栈的定义:操作在表的尾端进行的线性表,栈顶:TOP,栈底:Bottom.栈中没有数据:空栈Empty Stack 表示方法:S=(a1,a2,a3,a4……..an)a1为栈底的元素,an为栈顶的元素.这N个数据按照先后顺序插入到栈内,找出栈内数据则相反 遵循的原则(Las

第二十三篇 玩转数据结构——栈(Stack)

1.. 栈的特点: 栈也是一种线性结构: 相比数组,栈所对应的操作是数组的子集: 栈只能从一端添加元素,也只能从这一端取出元素,这一端通常称之为"栈顶": 向栈中添加元素的过程,称之为"入栈",从栈中取出元素的过程称之为"出栈": 栈的形象化描述如下图: "入栈"的顺序若为1-2-3-4,那么出栈的顺序只能为4-3-2-1,即,栈是一种"后进先出"(Last In First Out)的数据结构: 从用户的

南阳OJ-2 括号配对 (数据结构-栈的应用)

括号配对问题 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描述 现在,有一行括号序列,请你检查这行括号是否配对. 输入 第一行输入一个数N(0<N<=100),表示有N组测试数据.后面的N行输入多组输入数据,每组输入数据都是一个字符串S(S的长度小于10000,且S不是空串),测试数据组数少于5组.数据保证S中只含有"[","]","(",")"四种字符 输出 每组输入数据的输出占一行,

poj 2082 Terrible Sets (数据结构 ——栈 STL)

 Terrible Sets Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 2999   Accepted: 1549 Description Let N be the set of all natural numbers {0 , 1 , 2 , . . . }, and R be the set of all real numbers. wi, hi for i = 1 . . . n are some elem

C++表达式求值(利用数据结构栈)

唉,刚刚用C++又又一次写了一个较完好的表达式求值程序,最后精简后程序还不到100行.这不经让我 想到了大一上学期刚学c语言时自己费了好大的劲,写了几百行并且功能还不是非常齐全(当时还不能计算有括号的表 达式)的简单计算器程序.刚把两个程序对照了一下.感触还是挺深的,同一时候也再一次体现了数据结构在程序设计 中的重要性. 曾经的那个程序有漏洞并且逻辑复杂,所以就不提了,仅仅说说如今改进后的程序,其思想主要是用到了 栈先进后出的数据结构.在该程序中建有两个栈:一个用于存储运算符,还有一个用于存储操

数据结构——栈——寻找下一个较大元素

题目描述 给出一个数组,向右寻找每一个元素的下一个较大的元素,没有更大的则为-1 举例 {4,6,1,3,2,5} 则求得的答案应为 {6,-1,3,5,5,-1} 题目分析 首先对于这样的题目,我们总是先想到最简单的,那么就是枚举,每次循环一个元素,不停的向右找就可以了.时间复杂度应该是n^2 但是这样肯定是不够用的. 然后我们考虑,这道题我们实际上遇到的问题是什么? 其实简单的说,这道题的意思是,在变化的数组中找到下一个较大的值. 难点在于,数组元素的变化,以及不是找最大值,而是找下一个较大

C数据结构-栈和队列,括号匹配举例

1.栈和队列是两种特殊的线性表 运算操作被限定只能在表的一端或两端插入,删除元素,故也称它们为限定的线性表结构 2.栈的基本运算 1).Stackinit(&s) 构造一个空栈 2).Stackempty(s) 判断s是否为空栈,当s为空栈时,函数返回值1 否则 0 3).Push(&s,x)  在栈s 的顶部插入元素x,简称将x入 栈 4).Pop(&s,&x) 在栈s 中删除顶元并将其值保存在x单元中返回,简称将x出栈 5)Gettop(s,&x)  读s栈中的

数据结构-栈的压入、弹出序列

题目:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个顺序是否是该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压栈序列,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但是4,3,5,1,2就不可能是. 分析:首先利用图像进行形象化的理解.可以发现其压入的顺序并不是所有的一次性压入.同时要考虑栈是否为空.以及其长度.这段代码写的很痛苦,继续训练. /* 剑指offer面试题22 */ #include <iostream> #include &

利用数据结构栈求解迷宫问题

本段程序主要利用数据结构栈的先进后出特点,实现回溯求解迷宫路径问题. #include<iostream> #include<stack> using namespace std; //坐标类 struct Point { int x; int y; }; //地图类 template<int A> struct Map { int (*p)[A]; int row;//行数 int col;//列数 }; //start起始点, end终止点 template<

堆(heap)和栈(stack)几点认识

堆(heap)和栈(stack)主要的区别由以下几点:1.管理方式不同:2.空间大小不同:3.产生碎片不同:4.生长方向不同:5.分配归属不同:6.分配效率不同:7.存取效率不同:管理方式:对于栈来讲,释放是由程序自动管理,无需在程序中手工控制:对于堆来说,释放工作由程序员控制,容易产生memory leak.产生碎片:对于堆来讲,频繁的new/delete,malloc/free势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低.对于栈来讲,则不会存在这个问题,因为栈是先进后出的队