從瀏覽器到棧

 

從瀏覽器到棧

 

 


棧是什麼?

說到棧咱們老是先想到 FILO(first in last out), 有沒有什麼更貼切一點的例子呢?html

有了,洗盤子其實和棧很像,咱們老是從盤子的頂部拿起盤子,第一個放的盤子是最後一個拿出來的,符合FILO, 這樣咱們就能很天然地理解(stack),這種數據結構咯。java

如何實現一個棧?

上面咱們講了什麼是棧,那讓咱們動手實現一個吧。實現棧,咱們既能夠用數組,也能夠用鏈表。前一種叫作順序棧,後一種則是 鏈式棧.數組

  • 代碼瀏覽器

    // 基於數組實現的順序棧
    class ArrayStack{
        private String[] items;
        private int count; // 棧中元素個數
        private int n;     // 棧的大小 
    
        // 初始化數組,申請一個大小爲n的數組空間
        public ArrayStack(int n){
            this.items = new String[n];
            this.n = n;
            this.count = 0;
        }
    
        // 入棧
        public boolean push(String item){
            if(count==n) return false;
            items[count] = item;
            ++count;
            return true;
        }
    
        // 出棧
        public String pop(){
            // 棧爲空,則直接返回 null
            if(count == 0) return null;
            // 返回下標爲 count-1 的數組元素
            String tmp = items[count-1];
            --count;
            return tmp;
        }
    }
    
    // 基於鏈表實現的棧
    class StackBasedOnLinkedList {
        private Node top = null;
    
        public void push(int value) {
            Node newNode = new Node(value, null);
            if (top == null) {
                top = newNode;
            } else {
                newNode.next = top;
                top = newNode;
            }
        }
    
        // -1表示棧中沒有數據
        public int pop() {
            if (top == null)
                return -1;
            int value = top.data;
            top = top.next;
            return value;
        }
    
        public void printAll() {
            Node p = top;
            while (p != null) {
                System.out.print(p.data + " ");
                p = p.next;
            }
            System.out.println();
        }
    
        private static class Node {
            private int data;
            private Node next;
    
            public Node(int data, Node next) {
                this.data = data;
                this.next = next;
            }
    
            public int getData() {
                return data;
            }
        }
    }
  • 固然你還能夠本身嘗試實現一下順序棧的擴容,它的攤還時間複雜度爲O(1)。數據結構

棧的應用

表達式

關於表達式,個人第一反應是後綴表達式(逆波蘭表示法), 不過咱們今天不討論這個,先來說一講簡單的四則運算。若是咱們要計算 3 + 5×8 -6 ,如何用棧實現呢?函數

  • 圖例
    圖源 轉載使用,如侵權則聯繫我刪除!
    equ
  • 分析
    如圖,咱們使用兩個棧實現。其中一個保存操做數的棧,另外一個是保存運算符的棧。咱們從左向右遍歷表達式,當遇到數字,咱們就直接壓入操做數棧;當遇到運算符,就與運算符的棧頂元素比較。若是比棧頂運算符的優先級高,就將當前運算符壓入棧;若是比棧頂元素的優先級低或者相同,從運算符棧中取棧頂運算符,從操做數的棧頂取2個操做數,而後計算,再把結果壓入操做數棧,繼續比較。

括號匹配

咱們假設表達式中只包含三種括號,圓括號(), 方括號[] , 和花括號{}, 而且他們能夠任意嵌套。那麼如何檢查他們是否合法呢?
咱們能夠用棧來保存未匹配的左括號,從左到右依次掃描字符串。當掃到左括號時,將其壓入棧中當掃描到右括號時,從棧頂取出一個左括號。若是可以匹配,則繼續掃描剩下的字符串。若是掃描的過程當中,遇到不能配對的右括號,或者棧中沒有數據,則爲非法格式。this

瀏覽器

假如,咱們打開了 a,b,c 三個頁面,先從 c 回退到a, 再從 a 前進到 b,示意圖以下,運用雙棧實現。
圖源 轉載使用,如侵權則聯繫我刪除!
step1
step2
step3
step4spa

補充

最後,咱們思考兩個問題:3d

  • 咱們在寫程序時會發現,程序是用函數調用棧來保存臨時變量的,爲何要用「棧」來保存臨時變量呢?用其餘的數據結構不行嗎?
  • 咱們都知道,JVM內存管理中有個"堆棧"的概念。 棧內存用來存儲局部變量和方法調用,堆內存用來存儲Java中的對象。那麼JVM裏面的「棧「和咱們這裏說的是否是一回事呢?若是不是,那他爲何又叫作"棧"呢?
相關文章
相關標籤/搜索