數據結構-棧

數據結構-棧

定義

棧(英語:stack)又稱爲堆棧或堆疊,棧作爲一種數據結構,它按照先進後出的原則存儲數據,先進入的數據被壓入棧底,最後的數據在棧頂,需要讀數據的時候從棧頂開始彈出數據(最後一個數據被第一個讀出來)。
  由於堆疊數據結構只允許在一端進行操作,因而按照後進先出(LIFO, Last In First Out)的原理運作。棧也稱爲後進先出表

棧的應用場景

undo操作(撤銷)

  • 例如:將操作的每組數據存入棧中,如果想要撤銷,只需要彈出棧頂元素,就可以恢復上一步操作了。

程序調用的系統棧

  • 例如:A方法調用B方法得到返回值,B調用C得到返回值,A操作走到了B方法,這個時候可以將A的代碼位置存儲到棧中,然後走到B方法,B操作走到了C方法,這個時候可以將B的代碼位置存儲到棧中。最後C執行完成,根據棧的結構開始彈出數據,一步一步再走回A方法。

判斷括號是否有效。下文會有代碼實現(詳細規則描述可以參考leetcode第20題)

  • 開括號必須用同一類型的括號閉合。

  • 開方括號必須按正確順序閉合。

  • 例如:正確的:{[()]} {()} 等 。錯誤的:[{(})] [}{()] 等。

自定義棧基類的代碼實現

  • 棧在java.util有一個工具類,先不用,自定義實現一個

創建一個接口,用來統一規範所有棧實現

package com.datastructure.stack;

public interface Stack<E> {

    /**
     * 向棧插入元素
     * @param e
     */
    public  void push(E e);


    /**
     * 取出最上面的元素,並且返回
     * @return
     */
    public E pop();

    /**
     * 獲取棧的大小
     * @return
     */
    public int getSize();

    /**
     * 判斷棧是否爲空
     * @return
     */
    public boolean isEmpty();

    /**
     * 獲取棧最上面的元素
     * @return
     */
    public E peek();
}

用基於數組的方式來實現一個棧(上篇文章數據結構-數組所寫的自定義數組)

package com.datastructure.stack;

import com.datastructure.array.Array;

/**
 * @program: test
 * @description:
 * @author: Mr.Yang
 * @create: 2019-05-02 15:27
 **/
public class ArrayStack<E> implements Stack<E>{

    Array<E> array;

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



    public ArrayStack(){
        array=new Array<E>();
    }

    @Override
    public void push(E e) {
        array.addLast(e);
    }

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

    @Override
    public int getSize() {
        return array.getSize();
    }


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


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

    /**
     * 獲取容量值
     * @return
     */
    public int getCapacity(){
        return array.getCapacity();
    }


    @Override
    public String toString(){
        StringBuffer sb = new StringBuffer();
        sb.append("stack: ");
        sb.append("[");
        for(int i=0;i<array.getSize();i++){
            sb.append(array.get(i));
            if(i!=array.getSize()-1){
                sb.append(", ");
            }
        }
        sb.append("]            right value is stack top");
        return sb.toString();
    }
}

測試代碼

package com.datastructure.stack;

/**
 * @program: test
 * @description:
 * @author: Mr.Yang
 * @create: 2019-05-02 16:11
 **/
public class StackTest {

    public static void main(String[] args) {
        ArrayStack<Integer> integerArrayStack = new ArrayStack<>();
        for(int i=0;i<5;i++){
            integerArrayStack.push(i);
            System.out.println(integerArrayStack);
        }
        Integer pop = integerArrayStack.pop();
        System.out.println("----移除上級元素----value is "+pop);
        System.out.println("-------------移除之後的棧打印------------------");
        System.out.println(integerArrayStack);
    }
}

測試結果

stack: [0]            right value is stack top
stack: [0, 1]            right value is stack top
stack: [0, 1, 2]            right value is stack top
stack: [0, 1, 2, 3]            right value is stack top
stack: [0, 1, 2, 3, 4]            right value is stack top
----移除上級元素----value is 4
-------------移除之後的棧打印------------------
stack: [0, 1, 2, 3]            right value is stack top

leetCode第20題,花括號正確閉合

思路

  • 根據棧的數據結構特點,我們可以先將所有左括號‘[{(’放進棧中,然後判斷當前字符如果是‘)]}’這種的右括號,但是棧頂的括號卻不匹配,返回false

  • 注意控制判斷

  • 這裏使用java自帶的棧工具類來實現

  • leetcode給的測試例子:

  1 2 3 4 5
輸入例子 () ()[]{} (] ([)] {[]}

代碼實現

package com.datastructure.stack;

import java.util.Stack;

/**
 * @program: test
 * @description:
 * @author: Mr.Yang
 * @create: 2019-05-02 16:59
 **/
public class Solution {
    public static void main(String[] args) {
        Solution solution = new Solution();
        System.out.println(solution.isValid("{\"name\": \"網站\",\"num\": 3,\"sites\": [ \"Google.com\", \"Taobao.com\", \"Waibo.wang\" ]}"));
    }
    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();
    }

    /*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 toChar = characters.pop();
                if(c == ')' && toChar != '('){
                    return false;
                }
                if(c == '}' && toChar != '{'){
                    return false;
                }
                if(c == ']' && toChar != '['){
                    return false;
                }
            }
        }
        return characters.isEmpty();
    }*/
}

如果想實現更多字符串關於括號的匹配,如JSON等等,可以根據棧的特點來實現

 


代碼例子GIT地址:https://github.com/tuoluofusijiyang/designPattern.git

項目簡介:這個項目是我做測試,學習的主要項目,目前裏面包含了:

  • 一些設計模式的demo(抽象工程模式,適配器模式,外觀模式,命令模式,裝飾者模式等等)

  • 即將學習的數據結構demo,數組,棧,後續還會持續更新數據結構,可能會有隊列,鏈表,遞歸,紅黑樹,線段樹等等一系列,如果感興趣,歡迎留言。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章