從應用場景看棧

在 JavaScript 中,數組就是一個最簡單的棧了,在尾部操做的poppush也對應着出入棧的操做。so ?編程

棧只是種抽象概念,用鏈表 or 其它方式實現它都可。應用之解決問題正是它存在的緣由數組

場景一:遞歸

從前山上有座廟,廟裏有個老和尚和小和尚,老和尚給小和尚講故事:「從前山上有座廟......」數據結構

有名的斐波那契數列,手動地計算至關困難,即使有計算器在手。而在編程語言中,使用遞歸能夠很好地解決這個難題:編程語言

function F(n) {
  return F(n-1) + F(n-2);
}
複製代碼

重點來了,計算機如何實現遞歸?這是一個很籠統的概念,由於等於這個加那個,那個再加這個...... 知其因此然而不知其然。應用棧的結構,咱們能夠把未知的結果推入棧內,在彈出的時候逐個計算。 以下圖函數

棧應用 - 斐波那契數列

代碼解釋:spa

function recursion() {
  // 調用棧
  const stack = [];

  // 解析時
  // 推入棧
  // 通常來講,棧有大小限制,若是本身寫了個無限遞歸的函數,那調用棧一直增長,最後溢出
  for (let i = n; i > 0; i--) {
    stack.push(F(i));
  }

  // 執行時
  // 後入先出,彈出
  for (let i = 3; i <= n; i++) {
    F(n-2) = stack.pop();
    F(n-1) = stack.pop();

    F(n) = F(n-1) + F(n-2)
    
    // 計算完成後再推入棧內
    stack.push(F(n))
  }

  // 執行完成,棧內剩下最終結果,彈出並返回
  if (n) return stack.pop()
}
複製代碼

場景二:四則運算

數學老師:「先乘除,後加減,有括號先算括號。」code

分析下計算機四則運算的步驟:cdn

  1. 定義運算符功能
  2. 優先級:乘除 >> 加減
  3. 有括號優先計算括號

示例:(1 + 2) x 3 - 4 ÷ 5blog

括號內優先計算,立馬得出結果,咋一想還蠻符合隊列的規則,先入先出嘛。但在有多個括號的狀況下,優先計算最裏面的括號,這樣就只能推入棧中慢慢計算了。遞歸

可是怎麼優雅地推入棧內計算,有個偉大的科學家解決了這個難題,波蘭邏輯學家想到了一種不須要括號的後綴表達式,稱之爲逆波蘭

示例後綴表達式:12+3*45/-

後綴表達式計算過程:

棧應用 - 後綴表達式計算

轉化後的計算簡直不要太簡單,來看看又是如何利用棧來轉的:

棧應用 - 四則運算

最後

直接從《大話數據結構》搬過來的磚。。。不過這本書真的比清華版數據結構易懂多了,正在啃的同窗安利下

相關文章
相關標籤/搜索