zoukankan      html  css  js  c++  java
  • 栈的定义

      栈(stack)又名堆栈,它是一种运算受限的线性表。其限制是仅允许在表的一端进行插入和删除运算。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。

      简而言之,这种数据结构类似于长条形的存储空间,并且一端封闭,它的特点是先入后出。

      数据呈现方式如下图:

      需要特别注意的是,栈是一种逻辑结构,并不是一种物理上存在的数据结构,如果你要实现一个栈来存储数据,你可以使用数组或链表来实现。

    入栈

      现在我们要在栈中添加一个数据100,将100这个数据压入栈(push)。

      栈只有一个入口,添加数据只能从栈顶一侧放入,新放入的数据位置成为新的栈顶。

    出栈

      出栈就是取出元素,专业术语叫做弹出元素(pop),因为它具有取出数据并且删除两个效果。

      这就没有了指定弹出哪一个数据的说法了,你只能说弹出一个数据,至于弹出哪一个?永远都是处在栈顶那一个。

      弹出一个数据:

      再弹出一个数据:

    效率

      无论是入栈还是出栈,都只是涉及到栈顶的那一个元素,不涉及其他元素的移动,所以栈的出栈入栈时间复杂度都是O(1)。

    使用场景

      栈在实战中使用场景应该很少,但肯定是有的,比如需要每次访问最新的数据时,就可以选择栈来存储数据。

      栈在计算机中是不可获取的机制,在CPU内部就有栈使用这个数据结构来进行函数调用和返回、数字转字符、表达式求值、走迷宫等等,只要数据的保存具有先进后出的需求,都优先考虑使用栈。

    代码实现

      栈的核心是入栈与出栈的规则,所以为了规避掉数据类型、扩容等问题,我这里使用动态数组ArrayList来实现

    /**
     * @Description 栈
     * @Author zhaobaolin
     * @Date 2019/5/26
     */
    public class MyStack<T> {
    
        private ArrayList<T> arr = new ArrayList<>();
    
        public void push(T data)
        {
            arr.add(data);
        }
        private boolean isEmpty()
        {
            return arr.isEmpty();
        }
    
        public T pop()
        {
            if(isEmpty()){
                return null;
            }
            int index = arr.size() - 1;
            T data = arr.get(index);
            arr.remove(index);
            return data;
        }
    
        public static void main(String[] args) {
            MyStack myStack = new MyStack();
            myStack.push("hello");
            myStack.push(666);
            myStack.push("world");
            myStack.push(888);
            System.out.println(myStack.pop());
            System.out.println(myStack.pop());
            System.out.println(myStack.pop());
            System.out.println(myStack.pop());
            System.out.println(myStack.pop());
        }
    }

    最小栈

    /**
     * @Description
     * @Author zhaobaolin
     * @Date 2019/5/26
     *
     *
     * 设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈。
     *
     * push(int x) -- 将元素 x 推入栈中。
     * pop() -- 删除栈顶的元素。
     * top() -- 获取栈顶元素。
     * getMin() -- 检索栈中的最小元素。
     */
    public class MinStack {
        private List arr;
        private int minIndex = -1;
        public MinStack() {
            arr = new ArrayList();
        }
    
        public void push(int x) {
            if(arr.isEmpty()){
                minIndex = 0;
            }
            arr.add(x);
            if(x < (int)arr.get(minIndex)){
                minIndex = arr.size() - 1;
            }
        }
    
        public void pop() {
            if(!arr.isEmpty()){
                int i = arr.size() - 1;
                arr.remove(i);
                if(i == this.minIndex){
                    this.minIndex = getArrayListMinIndex();
                }
            }
        }
    
        public int top() {
            if(arr.isEmpty()){
                return -1;
            }
            int i = arr.size() - 1;
            int data = (int) arr.get(i);
            if(i == this.minIndex){
                this.minIndex = getArrayListMinIndex();
            }
            return data;
        }
    
        private int getArrayListMinIndex()
        {
            if(arr.isEmpty()){
                return -1;
            }
            Object obj = Collections.min(arr);
            return arr.indexOf(obj);
        }
    
        public int getMin() {
            return this.minIndex >= 0 ? (int) arr.get(this.minIndex) : -1;
        }
    
        public static void main(String[] args) {
    
        //测试用例
    /*
            MinStack minStack = new MinStack();
            minStack.push(1);
            minStack.push(2);
            System.out.println(minStack.top()); //  --> 返回 2
            System.out.println(minStack.getMin()); //  --> 返回 1
            minStack.pop();
            System.out.println(minStack.getMin()); //  --> 返回 1
            System.out.println(minStack.top()); //  --> 返回 1
    */
    
    
    /*        MinStack minStack = new MinStack();
            minStack.push(-2);
            minStack.push(0);
            minStack.push(-3);
            System.out.println(minStack.getMin()); //  --> 返回 -3.
            minStack.pop();
            System.out.println(minStack.top());   //   --> 返回 0.
            System.out.println(minStack.getMin());//   --> 返回 -2.
            */
        }
    }

    有效的括号

    这也是一道痕经典的题

    /**
     * @Description
     * @Author zhaobaolin
     * @Date 2019/5/26
     *
     * 给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。
     *
     * 有效字符串需满足:
     * 左括号必须用相同类型的右括号闭合。
     * 左括号必须以正确的顺序闭合。
     * 注意空字符串可被认为是有效字符串。
     *
     * 例如:
     * 输入: "()"  输出: true
     * 输入: "()[]{}" 输出: true
     * 输入: "(]" 输出: false
     * 输入: "([)]" 输出: false
     * 输入: "{[]}" 输出: true
     * 输入: "(([]){})" 输出: true
     */
    public class Bracket {
        private Map map;
        private Stack stack;
    
        public Bracket() {
            map = new HashMap();
            map.put("(",")");
            map.put("{","}");
            map.put("[","]");
        }
    
        public boolean isValid(String s) {
            this.stack = new Stack();
    
            s = s.trim();
            int len = s.length();
            for(int i=0;i<len;i++){
                String str = s.substring(i,i+1);
    
                if(this.stack.empty()){
                    stack.push(str);
                    continue;
                }
    
                String peek = (String)stack.peek();
    
                //如果栈顶的元素不是该符号的对应 则判断该符号是否是起始符号
                if(str.equals(map.get(peek))){
                    stack.pop();
                }else{
                    if(map.containsKey(str)){
                        stack.push(str);
                    }else{
                        return false;
                    }
                }
            }
            return this.stack.empty();
        }
    
        public static void main(String[] args) {
            Bracket bracket = new Bracket();
            System.out.println(bracket.isValid("()"));  // true
            System.out.println(bracket.isValid("()[]{}")); // true
            System.out.println(bracket.isValid("(]"));  // false
            System.out.println(bracket.isValid("([)]"));    // false
            System.out.println(bracket.isValid("{[]}"));    // true
            System.out.println(bracket.isValid("(([]){})"));    // true
        }
    }
  • 相关阅读:
    装箱与拆箱,数组 糖不苦
    产生乱码的原因 糖不苦
    jQuery 库中的 $() 是什么? 糖不苦
    什么是jQuery 糖不苦
    ATM管理系统 糖不苦
    JS事件委托中同一个标签执行不同操作
    js实现36进制
    js+php+mysql实现的学生成绩管理系统
    两数之和
    函数防抖
  • 原文地址:https://www.cnblogs.com/fengyumeng/p/10861025.html
Copyright © 2011-2022 走看看