堆疊(Stack)

文章目錄

介紹

堆疊是資料結構的一種,將數據排成一列,可以把它想像在疊積木,資料不斷往上堆疊,每次取出資料時,只能從最上方的資料開始拿起

  • 後進先出原理,稱為 Last in First out ,簡稱 LIFO
  • 資料無index
  • 只能從最上方加入,並從最上方開始拿取

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

(圖片取自於Stacks & Queues)

複雜度

時間複雜度

Action動作 平均 最壞
訪問(Access)
O(n)
O(n)
搜尋(Search)
O(n)
O(n)
插入(Insertion)
O(1)
O(1)
刪除(Deletion)
O(1)
O(1)

空間複雜度

O(n)

空間複雜度隨著 Stack 中元素的數量線性增長

利用 JS 模擬 Stack

Js Array寫法

我們可以利用js array達成stack效果,利用push新增資料在末端,要取出資料使用pop方法即可

let stack = []; stack.push(92); // 新增資料 stack.push(46); stack.push(51); stack.push(53); stack.pop(); // 移除尾端資料

Object Property

以下利用物件導向實作

初始化Node

class Node { constructor(value) { this.value = value; this.next = null; } }

初始化Stack

新增頭跟尾

class Stack { constructor() { this.head = null; this.tail = null; this.length = 0; } }

Stack新增push方法

將物件插入 Stack 的頂端。

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

(圖片來自於visualgo)

  1. 創建一個新的節點 newNode 並將其初始化為 value
  2. 檢查是否為空串列,是的話則將 headtail 都指向新的節點
  3. 否則將 head 指向新的節點,並將新的節點的 next 屬性指向舊的 head(即舊的頂端)。
  4. stack 長度加一
push(value) { let newNode = new Node(value); if (this.head === null) { this.head = newNode; this.tail = newNode; } else { let temp = this.head; this.head = newNode; this.head.next = temp; } this.length++; }

Stack新增pop方法

移除並傳回在 Stack 頂端的物件。

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

(圖片來自於visualgo)

  1. 檢查是否為空列表,如果是,則返回 null
  2. 如果列表長度為 1,則將 headtail 都設置為 null,並將列表長度設置為 0,最後返回被移除的節點
  3. 如果列表長度大於 1,則將 head 設置為它的下一個節點,並將列表長度減 1,最後返回被移除的節點。
pop(){ if(this.head === null){ return null; } else if(this.length === 1){ let temp = this.head; this.head = null; this.tail = null; this.length = 0; return temp; } else { let temp = this.head; this.head = this.head.next; this.length--; return temp; } }

Stack新增peek方法

傳回 Stack 頂端的物件而不需移除它。

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

(圖片來自於visualgo)

  1. 檢查head是否為空,如果是,則返回 null
  2. 否則回傳head的值
peek() { if(this.head === null){ return null; } else { return this.head.value; } }

實戰

20. Valid Parentheses

題目說明

給定一個僅包含字符 '('')''{''}''['']' 的字符串 s,確定輸入字符串是否有效。

如果滿足以下條件,則輸入字符串有效:

  • 開括號必須由相同類型的括號閉合。
  • 打開的括號必須以正確的順序關閉。
  • 每個閉括號都有一個對應的相同類型的開括號。

實戰

詳細解法

  1. 數組openedclosed被定義為分別表示左括號和右括號。 然後將字符串 s 轉換為稱為 sarray 的字符數組,並使用for循環遍歷sarray
  2. 在循環的每次迭代中,檢查當前字符以查看它是否是左括號之一
  3. 如果是則將opened數組中的相應索引推送到stack數組中
  4. 如果不是,則當前字符必須是右括號
  5. 如果stack不為空,則檢查stack數組的最後一個元素,看它是否等於closed數組中的相應索引
  6. 如果等於相對應索引,則stack數組的最後一個元素pop出來(因為已找到匹配的括號並且可以將其刪除)
  7. 如果不是,函數返回 false
  8. 最後再檢查stack是否為空,空則返回true表示有效,否則反之
/** * @param {string} s * @return {boolean} */ var isValid = function(s) { let opened = ["(", "[", "{"] let closed = [")", "]", "}"] let sarray = [...s] let stack = [] for (let i = 0; i < sarray.length; i++) { if (opened.includes(sarray[i])) { stack.push(opened.indexOf(sarray[i])) } else { if(stack.length != 0 && stack[stack.length - 1] == closed.indexOf(sarray[i])) { stack.pop() } else { return false } } } return stack.length > 0 ? false : true };

@joe94113Tue, Feb 5, 2023 10:00 PM