堆疊(Stack)

堆疊(Stack)

Author: Jed. Feb 06, 2025

堆疊介紹

堆疊也是線性資料結構,他與Queue不同在於他是垂直的,這是甚麼意思呢? 我們直接看Stack的圖形。Stack是由上往下,其實就想像假設有個極端的電梯只能垂直進去,Insert時,一開始C先會先進去,接著B,再來A,由底部堆積上來,當電梯一到達樓層時,A會先出去,接著B,再換C,因此他有著先進後出(FILO)特性。

graph TD a["電梯入口"] A["A"] B["B"] C["C"] D["電梯後面鏡子"] a --> A --> B --> C --> D

push

Stack中將資料放入Stack這動作叫做push,下面來push一個D看看動作。

原本電梯例子

graph TD a["電梯入口"] A["A"] B["B"] C["C"] D["電梯後面鏡子"] a --> A --> B --> C --> D

這時候D進來了,就會像這樣。

graph TD a["電梯入口"] A["A"] B["B"] C["C"] D["電梯後面鏡子"] E["D"] a --> E --> A --> B --> C --> D

pop

pop為將Stack資料取出,這邊沿用電梯例子,當樓層到達時比喻於pop

graph TD a["電梯入口"] A["A"] B["B"] C["C"] D["電梯後面鏡子"] D --> C --> B --> A --> a

A就會先出去(取出),以此類推接著B,再來C

graph TD a["電梯入口"] B["B"] C["C"] D["電梯後面鏡子"] D --> C --> B --> a

實作Stack

我們可以使用list來實現Stack

class Stack:

    def __init__(self):
        self.stack = []

    def push(self, value):
        self.stack.append(value)

    def pop(self):
        self.stack.pop(-1)

    def size(self):
        return len(self.stack)

    def print_stack(self):
        print(self.stack)

接著push資料

stack = Stack()
stack.push('a')
stack.push('b')
stack.push('c')
stack.print_stack()

image.png

然後pop

stack.pop()
stack.print_stack()

image.png

Python Function Stack

Python中,Fcuntion的呼叫都是使用Stack,其實驗證這件事情很簡單,簡單定義三個Function分別為abc,而一開始call func_a,接著func_a call func_b,再來func_b call func_c

import traceback

def func_a():
    func_b()
    print("呼叫 func_a")

def func_b():
    func_c()
    print("呼叫 func_b")

def func_c():
    print("呼叫 func_c")

func_a()

接著你就會看到訊息,依序從呼叫 func_c —> 呼叫 func_b —> 呼叫 func_a 印出來,這就符合Stack先進後出概念。

image.png

Stack應用-Leetcode 20 Valid Parentheses

刷過Leetcode一定有做過這題,利用Stack來驗證符合是否成對來看看題目

題目:

Given a string s containing just the characters (, ), {, }, [ and ], determine if the input string is valid.

Conditions for a Valid String:

  1. Open brackets must be closed by the same type of brackets.
  2. Open brackets must be closed in the correct order.
  3. Every close bracket has a corresponding open bracket of the same type.

Examples:

Example 1:

Input: s = "()"

Output: true

Example 2:

Input: s = "()[]{}"

Output: true

Example 3:

Input: s = "(]"

Output: false

Example 4:

Input: s = "([])"

Output: true

Constraints:

  • 1 <= s.length <= 10^4
  • s consists of parentheses only: '()[]{}'

解答使用Stack,先將左符號PushStack直到遇到右符號,遇到右符號後開始簡單是否成對,如果是就繼續並popStack,如果不是那直接return False

def is_valid(s: str) -> bool:
    stack = []
    mapping = {')': '(', '}': '{', ']': '['}

    for char in s:
        if char in mapping:
            top_element = stack.pop() if stack else '#'
            if mapping[char] != top_element:
                return False
        else:
            stack.append(char)

    return not stack

print(is_valid("{(()})"))