演算法 2025-08-19

Link list in python

為了解 LeetCode 2. Add Two Numbers 而整理的 Python 鏈結串列教學。八個核心概念,每個概念都搭配一段可以直接執行的程式碼。

#Linked List#Python#資料結構#教學

前言

為了完成 LeetCode 題目 2. Add Two Numbers,我特地學習了 Python 中的 Linked List。不過我花了大約一小時的時間翻閱中英文影片及文章,卻始終找不到滿意的解說。

於是,我請 AI 當我的老師,生成了一篇 Python Linked List 教學。我覺得這份教學相當不錯,它以「一個概念搭配一段程式碼」的方式具體呈現,讓讀者能更有效地理解。

因此,我將這份內容整理成文章,分享給大家。希望大家會喜歡❤️

食用方式

首先,建議在閱讀每一概念時,將該段概念的程式碼執行起來,如此可以更具體且清楚的看到對應的使用方式。其次,這篇文章不建議以教科書的方式,讀完後再練習,而是當作一本字典,有碰到疑問再來查閱。

祝用餐愉快~~


概念1️⃣:什麼是節點(Node)

節點是鏈結串列的基本組成單位,包含兩個部分:

  • data:儲存實際資料
  • next:指向下一個節點的指標
class Node:
    """節點類別 - 鏈結串列的基本單位"""
    def __init__(self, data):
        self.data = data    # 儲存資料
        self.next = None    # 指向下一個節點的指標

    def __str__(self):
        return f"Node({self.data})"

# === 程式碼示範 ===
print("=== 節點概念示範 ===")

# 建立三個獨立的節點
node1 = Node(10)
node2 = Node(20)
node3 = Node(30)

print(f"節點1: {node1}, 資料: {node1.data}, 下一個節點: {node1.next}")
print(f"節點2: {node2}, 資料: {node2.data}, 下一個節點: {node2.next}")
print(f"節點3: {node3}, 資料: {node3.data}, 下一個節點: {node3.next}")

print("\n手動連接節點:")
# 手動建立連結關係
node1.next = node2  # node1 指向 node2
node2.next = node3  # node2 指向 node3
# node3.next 保持 None (串列結尾)

print(f"節點1 指向: {node1.next}")
print(f"節點2 指向: {node2.next}")
print(f"節點3 指向: {node3.next}")

print("\n遍歷連結的節點:")
current = node1
while current:
    print(f"當前節點資料: {current.data}")
    current = current.next

概念2️⃣:什麼是鏈結串列(Linked List)

鏈結串列是由節點組成的線性資料結構,需要一個 head 指標來記錄第一個節點的位置。

class Node:
    def __init__(self, data):
        self.data = data
        self.next = None

class LinkedList:
    """鏈結串列類別"""
    def __init__(self):
        self.head = None    # 指向第一個節點
        self.size = 0       # 記錄串列長度

    def is_empty(self):
        """檢查串列是否為空"""
        return self.head is None

    def display(self):
        """顯示整個串列"""
        if self.is_empty():
            print("串列為空:None")
            return

        elements = []
        current = self.head
        while current:
            elements.append(str(current.data))
            current = current.next

        print(" -> ".join(elements) + " -> None")

# === 程式碼示範 ===
print("=== 鏈結串列基本結構示範 ===")

# 建立空的鏈結串列
ll = LinkedList()
print(f"空串列狀態:")
print(f"head 指標: {ll.head}")
print(f"是否為空: {ll.is_empty()}")
print(f"串列長度: {ll.size}")
ll.display()

print("\n手動建立有資料的串列:")
# 手動建立節點並連結
ll.head = Node(100)
ll.head.next = Node(200)
ll.head.next.next = Node(300)
ll.size = 3

print(f"head 指標指向: Node({ll.head.data})")
print(f"是否為空: {ll.is_empty()}")
print(f"串列長度: {ll.size}")
ll.display()

print(f"\n串列結構視覺化:")
print(f"head -> [100|•] -> [200|•] -> [300|None]")
print(f"        Node1      Node2      Node3")

概念3️⃣:在開頭新增節點

在串列開頭插入新節點是最簡單的操作,只需要:

  1. 建立新節點
  2. 新節點的 next 指向原本的 head
  3. 更新 head 指向新節點
class Node:
    def __init__(self, data):
        self.data = data
        self.next = None

class LinkedList:
    def __init__(self):
        self.head = None
        self.size = 0

    def prepend(self, data):
        """在串列開頭插入新節點"""
        # 步驟1: 建立新節點
        new_node = Node(data)

        # 步驟2: 新節點指向原本的head
        new_node.next = self.head

        # 步驟3: 更新head指向新節點
        self.head = new_node

        # 步驟4: 更新串列長度
        self.size += 1

        print(f"✅ 在開頭插入: {data}")

    def display(self):
        """顯示串列"""
        if self.head is None:
            print("串列為空")
            return

        elements = []
        current = self.head
        while current:
            elements.append(str(current.data))
            current = current.next

        print("串列內容: " + " -> ".join(elements) + " -> None")
        print(f"串列長度: {self.size}")

# === 程式碼示範 ===
print("=== 在開頭新增節點示範 ===")

ll = LinkedList()

print("初始狀態:")
ll.display()

print("\n第一次插入 (插入到空串列):")
ll.prepend(10)
ll.display()

print("\n第二次插入:")
ll.prepend(20)
ll.display()

print("\n第三次插入:")
ll.prepend(30)
ll.display()

print("\n📝 觀察結果:")
print("- 每次插入的元素都成為新的第一個節點")
print("- 插入順序:10 -> 20 -> 30")
print("- 串列順序:30 -> 20 -> 10 (相反順序)")
print("- 時間複雜度:O(1) - 非常快速!")

# 視覺化過程
print("\n🔍 插入過程視覺化:")
print("初始: head -> None")
print("插入10: head -> [10|None]")
print("插入20: head -> [20|•] -> [10|None]")
print("插入30: head -> [30|•] -> [20|•] -> [10|None]")

概念4️⃣:在末尾新增節點

在串列末尾插入新節點需要找到最後一個節點,步驟:

  1. 建立新節點
  2. 如果串列為空,新節點成為 head
  3. 否則遍歷到最後一個節點,將其 next 指向新節點
class Node:
    def __init__(self, data):
        self.data = data
        self.next = None

class LinkedList:
    def __init__(self):
        self.head = None
        self.size = 0

    def append(self, data):
        """在串列末尾插入新節點"""
        # 步驟1: 建立新節點
        new_node = Node(data)

        # 步驟2: 如果串列為空,新節點成為head
        if self.head is None:
            self.head = new_node
            print(f"✅ 插入到空串列: {data}")
        else:
            # 步驟3: 找到最後一個節點
            current = self.head
            position = 0
            print(f"🔍 尋找最後一個節點...")

            while current.next is not None:
                print(f"   位置 {position}: 當前節點 {current.data}, 下一個存在")
                current = current.next
                position += 1

            print(f"   位置 {position}: 找到最後節點 {current.data}")

            # 步驟4: 將最後節點的next指向新節點
            current.next = new_node
            print(f"✅ 在末尾插入: {data}")

        # 步驟5: 更新串列長度
        self.size += 1

    def display(self):
        """顯示串列"""
        if self.head is None:
            print("串列為空")
            return

        elements = []
        current = self.head
        while current:
            elements.append(str(current.data))
            current = current.next

        print("串列內容: " + " -> ".join(elements) + " -> None")
        print(f"串列長度: {self.size}")

# === 程式碼示範 ===
print("=== 在末尾新增節點示範 ===")

ll = LinkedList()

print("初始狀態:")
ll.display()

print("\n第一次插入 (插入到空串列):")
ll.append(10)
ll.display()

print("\n第二次插入:")
ll.append(20)
ll.display()

print("\n第三次插入:")
ll.append(30)
ll.display()

print("\n📝 觀察結果:")
print("- 每次插入的元素都成為最後一個節點")
print("- 插入順序:10 -> 20 -> 30")
print("- 串列順序:10 -> 20 -> 30 (相同順序)")
print("- 時間複雜度:O(n) - 需要遍歷到最後")

# 視覺化過程
print("\n🔍 插入過程視覺化:")
print("初始: head -> None")
print("插入10: head -> [10|None]")
print("插入20: head -> [10|•] -> [20|None]")
print("插入30: head -> [10|•] -> [20|•] -> [30|None]")

print("\n⚡ 效能比較:")
print("prepend (開頭插入): O(1) - 不需遍歷")
print("append (末尾插入):  O(n) - 需要遍歷到最後")

概念5️⃣:在指定位置新增節點

在指定位置插入節點需要先移動到正確位置,步驟:

  1. 檢查位置是否有效
  2. 如果是位置0,等同於開頭插入
  3. 否則移動到插入位置的前一個節點
  4. 調整指標連結
class Node:
    def __init__(self, data):
        self.data = data
        self.next = None

class LinkedList:
    def __init__(self):
        self.head = None
        self.size = 0

    def prepend(self, data):
        """在開頭插入 (輔助方法)"""
        new_node = Node(data)
        new_node.next = self.head
        self.head = new_node
        self.size += 1

    def insert_at_position(self, position, data):
        """在指定位置插入新節點"""
        # 步驟1: 檢查位置是否有效
        if position < 0 or position > self.size:
            print(f"❌ 錯誤:位置 {position} 超出範圍 (0-{self.size})")
            return

        print(f"🎯 要在位置 {position} 插入資料 {data}")

        # 步驟2: 如果是位置0,等同於開頭插入
        if position == 0:
            print("   這是位置0,使用開頭插入方式")
            self.prepend(data)
            return

        # 步驟3: 建立新節點
        new_node = Node(data)

        # 步驟4: 移動到插入位置的前一個節點
        current = self.head
        print(f"🔍 尋找位置 {position-1} (插入位置的前一個)...")

        for i in range(position - 1):
            print(f"   步驟 {i}: 當前在節點 {current.data}")
            current = current.next

        print(f"   ✅ 找到前一個節點: {current.data}")

        # 步驟5: 調整指標連結
        print(f"🔗 調整指標連結...")
        print(f"   新節點 {data} 指向 {current.next.data if current.next else 'None'}")
        new_node.next = current.next  # 新節點指向原本的下一個節點

        print(f"   節點 {current.data} 指向新節點 {data}")
        current.next = new_node       # 前一個節點指向新節點

        # 步驟6: 更新串列長度
        self.size += 1
        print(f"✅ 成功在位置 {position} 插入: {data}")

    def display(self):
        """顯示串列與位置"""
        if self.head is None:
            print("串列為空")
            return

        elements = []
        positions = []
        current = self.head
        pos = 0

        while current:
            elements.append(str(current.data))
            positions.append(f"[{pos}]")
            current = current.next
            pos += 1

        print("位置:    " + "    ".join(positions))
        print("串列內容: " + " -> ".join(elements) + " -> None")
        print(f"串列長度: {self.size}")

# === 程式碼示範 ===
print("=== 在指定位置新增節點示範 ===")

ll = LinkedList()

print("建立初始串列:")
ll.prepend(30)  # 位置0
ll.prepend(20)  # 位置0 (30變成位置1)
ll.prepend(10)  # 位置0 (20變成位置1, 30變成位置2)
ll.display()

print("\n=== 測試各種位置插入 ===")

print("\n1️⃣ 在位置 0 插入 (開頭):")
ll.insert_at_position(0, 5)
ll.display()

print("\n2️⃣ 在位置 2 插入 (中間):")
ll.insert_at_position(2, 15)
ll.display()

print("\n3️⃣ 在位置 5 插入 (末尾):")
ll.insert_at_position(5, 35)
ll.display()

print("\n4️⃣ 測試無效位置:")
ll.insert_at_position(10, 99)  # 超出範圍
ll.insert_at_position(-1, 99)  # 負數位置

print("\n📝 重要觀念:")
print("- 位置從 0 開始計算")
print("- 插入位置 i,原本位置 i 的元素會向後移")
print("- 時間複雜度:O(n) - 需要移動到指定位置")
print("- 空間複雜度:O(1) - 只需要建立一個新節點")

print("\n🔍 指標調整過程:")
print("插入前: A -> B -> C")
print("在位置1插入X:")
print("步驟1: 找到位置0的節點A")
print("步驟2: 新節點X指向B (X.next = A.next)")
print("步驟3: 節點A指向X (A.next = X)")
print("結果: A -> X -> B -> C")

概念6️⃣:刪除節點

刪除節點需要重新連接指標,主要有兩種方式:

  • 按值刪除:找到指定值的第一個節點並刪除
  • 按位置刪除:刪除指定位置的節點
class Node:
    def __init__(self, data):
        self.data = data
        self.next = None

class LinkedList:
    def __init__(self):
        self.head = None
        self.size = 0

    def append(self, data):
        """在末尾插入 (輔助方法)"""
        new_node = Node(data)
        if self.head is None:
            self.head = new_node
        else:
            current = self.head
            while current.next:
                current = current.next
            current.next = new_node
        self.size += 1

    def delete_by_value(self, data):
        """按值刪除節點"""
        if self.head is None:
            print(f"❌ 串列為空,無法刪除 {data}")
            return

        print(f"🎯 要刪除值為 {data} 的節點")

        # 情況1: 要刪除的是第一個節點
        if self.head.data == data:
            print(f"   找到目標!要刪除的是第一個節點")
            deleted_node = self.head
            self.head = self.head.next  # head指向下一個節點
            self.size -= 1
            print(f"✅ 已刪除第一個節點: {deleted_node.data}")
            return

        # 情況2: 要刪除的是其他節點
        current = self.head
        position = 0
        print(f"🔍 搜尋目標節點...")

        while current.next and current.next.data != data:
            print(f"   位置 {position}: 檢查節點 {current.data} 的下一個節點")
            current = current.next
            position += 1

        # 找到目標節點
        if current.next:
            print(f"   找到目標!位置 {position+1}: {current.next.data}")
            deleted_node = current.next
            print(f"🔗 調整指標: {current.data} 跳過 {deleted_node.data} 指向 {deleted_node.next.data if deleted_node.next else 'None'}")
            current.next = current.next.next  # 跳過要刪除的節點
            self.size -= 1
            print(f"✅ 已刪除節點: {deleted_node.data}")
        else:
            print(f"❌ 找不到值為 {data} 的節點")

    def delete_at_position(self, position):
        """按位置刪除節點"""
        if position < 0 or position >= self.size:
            print(f"❌ 位置 {position} 超出範圍 (0-{self.size-1})")
            return

        print(f"🎯 要刪除位置 {position} 的節點")

        # 情況1: 刪除第一個節點
        if position == 0:
            deleted_data = self.head.data
            self.head = self.head.next
            self.size -= 1
            print(f"✅ 已刪除位置 0 的節點: {deleted_data}")
            return

        # 情況2: 刪除其他位置的節點
        current = self.head
        print(f"🔍 移動到位置 {position-1}...")

        for i in range(position - 1):
            print(f"   步驟 {i}: 當前在節點 {current.data}")
            current = current.next

        print(f"   到達位置 {position-1}: {current.data}")

        deleted_node = current.next
        print(f"🔗 調整指標: {current.data} 跳過 {deleted_node.data} 指向 {deleted_node.next.data if deleted_node.next else 'None'}")
        current.next = current.next.next
        self.size -= 1
        print(f"✅ 已刪除位置 {position} 的節點: {deleted_node.data}")

    def display(self):
        """顯示串列與位置"""
        if self.head is None:
            print("串列為空")
            return

        elements = []
        positions = []
        current = self.head
        pos = 0

        while current:
            elements.append(str(current.data))
            positions.append(f"[{pos}]")
            current = current.next
            pos += 1

        print("位置:    " + "    ".join(positions))
        print("串列內容: " + " -> ".join(elements) + " -> None")
        print(f"串列長度: {self.size}")

# === 程式碼示範 ===
print("=== 刪除節點示範 ===")

ll = LinkedList()

print("建立測試串列:")
for value in [10, 20, 30, 40, 50]:
    ll.append(value)
ll.display()

print("\n=== 按值刪除測試 ===")

print("\n1️⃣ 刪除中間的值 (30):")
ll.delete_by_value(30)
ll.display()

print("\n2️⃣ 刪除第一個值 (10):")
ll.delete_by_value(10)
ll.display()

print("\n3️⃣ 嘗試刪除不存在的值 (99):")
ll.delete_by_value(99)
ll.display()

print("\n=== 按位置刪除測試 ===")

print("\n4️⃣ 刪除位置 1 的節點:")
ll.delete_at_position(1)
ll.display()

print("\n5️⃣ 刪除位置 0 的節點 (第一個):")
ll.delete_at_position(0)
ll.display()

print("\n6️⃣ 嘗試刪除無效位置:")
ll.delete_at_position(10)

print("\n📝 重要觀念:")
print("- 刪除節點的核心是重新連接指標")
print("- 刪除第一個節點需要特別處理 (更新head)")
print("- 刪除其他節點需要找到前一個節點")
print("- 時間複雜度:O(n) - 可能需要遍歷整個串列")

print("\n🔍 刪除過程視覺化:")
print("刪除前: A -> B -> C -> D")
print("刪除B的過程:")
print("步驟1: 找到B的前一個節點A")
print("步驟2: A的next指向C (跳過B)")
print("結果: A -> C -> D")
print("B節點被Python垃圾回收機制自動清理")

概念7️⃣:搜尋節點

搜尋節點需要從頭開始遍歷,直到找到目標值或到達串列末尾。

class Node:
    def __init__(self, data):
        self.data = data
        self.next = None

class LinkedList:
    def __init__(self):
        self.head = None
        self.size = 0

    def append(self, data):
        """在末尾插入 (輔助方法)"""
        new_node = Node(data)
        if self.head is None:
            self.head = new_node
        else:
            current = self.head
            while current.next:
                current = current.next
            current.next = new_node
        self.size += 1

    def search(self, data):
        """搜尋指定值,回傳位置索引"""
        if self.head is None:
            print(f"❌ 串列為空,無法搜尋 {data}")
            return -1

        print(f"🔍 搜尋值 {data}...")

        current = self.head
        position = 0

        # 遍歷整個串列
        while current:
            print(f"   位置 {position}: 檢查節點值 {current.data}")

            if current.data == data:
                print(f"✅ 找到了!值 {data} 在位置 {position}")
                return position

            current = current.next
            position += 1

        print(f"❌ 找不到值 {data}")
        return -1

    def search_all(self, data):
        """搜尋所有符合的值,回傳所有位置"""
        if self.head is None:
            print(f"❌ 串列為空,無法搜尋 {data}")
            return []

        print(f"🔍 搜尋所有值為 {data} 的節點...")

        current = self.head
        position = 0
        found_positions = []

        while current:
            print(f"   位置 {position}: 檢查節點值 {current.data}", end="")

            if current.data == data:
                found_positions.append(position)
                print(f" ✅ 符合!")
            else:
                print(f" ❌ 不符合")

            current = current.next
            position += 1

        if found_positions:
            print(f"✅ 找到 {len(found_positions)} 個符合的節點,位置: {found_positions}")
        else:
            print(f"❌ 找不到任何值為 {data} 的節點")

        return found_positions

    def get_at_position(self, position):
        """取得指定位置的值"""
        if position < 0 or position >= self.size:
            print(f"❌ 位置 {position} 超出範圍 (0-{self.size-1})")
            return None

        print(f"🎯 取得位置 {position} 的值...")

        current = self.head
        for i in range(position):
            print(f"   步驟 {i}: 經過節點 {current.data}")
            current = current.next

        print(f"✅ 位置 {position} 的值是: {current.data}")
        return current.data

    def contains(self, data):
        """檢查串列是否包含指定值"""
        return self.search(data) != -1

    def display(self):
        """顯示串列與位置"""
        if self.head is None:
            print("串列為空")
            return

        elements = []
        positions = []
        current = self.head
        pos = 0

        while current:
            elements.append(str(current.data))
            positions.append(f"[{pos}]")
            current = current.next
            pos += 1

        print("位置:    " + "    ".join(positions))
        print("串列內容: " + " -> ".join(elements) + " -> None")
        print(f"串列長度: {self.size}")

# === 程式碼示範 ===
print("=== 搜尋節點示範 ===")

ll = LinkedList()

print("建立測試串列:")
test_data = [10, 20, 30, 20, 40, 20, 50]
for value in test_data:
    ll.append(value)
ll.display()

print("\n=== 基本搜尋測試 ===")

print("\n1️⃣ 搜尋存在的值 (30):")
result = ll.search(30)
print(f"搜尋結果: {result}")

print("\n2️⃣ 搜尋不存在的值 (99):")
result = ll.search(99)
print(f"搜尋結果: {result}")

print("\n3️⃣ 搜尋重複的值 (只找第一個, 20):")
result = ll.search(20)
print(f"搜尋結果: {result}")

print("\n=== 進階搜尋測試 ===")

print("\n4️⃣ 搜尋所有重複的值 (20):")
positions = ll.search_all(20)

print("\n5️⃣ 按位置取值:")
ll.get_at_position(0)  # 第一個
ll.get_at_position(3)  # 中間
ll.get_at_position(6)  # 最後一個
ll.get_at_position(10) # 超出範圍

print("\n6️⃣ 檢查是否包含某值:")
print(f"包含 30? {ll.contains(30)}")
print(f"包含 99? {ll.contains(99)}")

print("\n📝 重要觀念:")
print("- 鏈結串列的搜尋只能從頭開始,逐一檢查")
print("- 時間複雜度:O(n) - 最壞情況需要檢查所有節點")
print("- 空間複雜度:O(1) - 只需要幾個變數")
print("- 無法像陣列一樣進行隨機存取 (不能直接跳到任意位置)")

print("\n🔍 搜尋過程視覺化:")
print("搜尋值 30 in [10, 20, 30, 40]:")
print("步驟1: 檢查位置0的10 ❌")
print("步驟2: 檢查位置1的20 ❌")
print("步驟3: 檢查位置2的30 ✅ 找到了!")
print("回傳位置: 2")

print("\n⚡ 效能比較:")
print("陣列隨機存取: O(1) - arr[index]")
print("鏈結串列存取: O(n) - 需要遍歷到目標位置")

概念8️⃣:遍歷和顯示串列

遍歷鏈結串列是最基本的操作,從 head 開始,依次訪問每個節點直到 None

class Node:
    def __init__(self, data):
        self.data = data
        self.next = None

    def __str__(self):
        return f"Node({self.data})"

class LinkedList:
    def __init__(self):
        self.head = None
        self.size = 0

    def append(self, data):
        """在末尾插入 (輔助方法)"""
        new_node = Node(data)
        if self.head is None:
            self.head = new_node
        else:
            current = self.head
            while current.next:
                current = current.next
            current.next = new_node
        self.size += 1

    def display_simple(self):
        """簡單顯示串列"""
        print("🔍 簡單遍歷:")
        if self.head is None:
            print("   串列為空")
            return

        current = self.head
        elements = []

        while current:
            elements.append(str(current.data))
            current = current.next

        print("   " + " -> ".join(elements) + " -> None")

    def display_detailed(self):
        """詳細顯示串列 (包含步驟)"""
        print("🔍 詳細遍歷過程:")
        if self.head is None:
            print("   串列為空,head = None")
            return

        current = self.head
        position = 0

        print(f"   開始遍歷,current = head = {current}")

        while current:
            print(f"   步驟 {position}: 位置 {position}, 當前節點 = {current.data}")
            print(f"            下一個節點 = {current.next.data if current.next else 'None'}")

            current = current.next
            position += 1

            if current:
                print(f"            移動到下一個節點...")
            else:
                print(f"            到達串列末尾,遍歷結束")

    def display_with_positions(self):
        """顯示串列與位置資訊"""
        print("📍 串列內容與位置:")
        if self.head is None:
            print("   串列為空")
            return

        current = self.head
        position = 0

        while current:
            print(f"   位置 [{position}]: {current.data}")
            current = current.next
            position += 1

        print(f"   總長度: {self.size}")

    def display_visual(self):
        """視覺化顯示串列結構"""
        print("🎨 視覺化串列結構:")
        if self.head is None:
            print("   head -> None")
            return

        current = self.head
        visual_parts = ["head"]

        while current:
            visual_parts.append(f"[{current.data}|•]")
            current = current.next

        visual_parts.append("None")
        print("   " + " -> ".join(visual_parts))

    def traverse_with_callback(self, callback):
        """使用回調函數遍歷串列"""
        print("🔄 使用回調函數遍歷:")
        if self.head is None:
            print("   串列為空")
            return

        current = self.head
        position = 0

        while current:
            callback(current.data, position)
            current = current.next
            position += 1

    def get_statistics(self):
        """計算串列統計資訊"""
        if self.head is None:
            return {"長度": 0, "總和": 0, "平均值": 0, "最大值": None, "最小值": None}

        current = self.head
        total = 0
        count = 0
        max_val = float('-inf')
        min_val = float('inf')

        print("📊 計算統計資訊...")
        while current:
            value = current.data
            print(f"   處理節點值: {value}")

            total += value
            count += 1
            max_val = max(max_val, value)
            min_val = min(min_val, value)

            current = current.next

        return {
            "長度": count,
            "總和": total,
            "平均值": total / count,
            "最大值": max_val,
            "最小值": min_val
        }

# === 程式碼示範 ===
print("=== 遍歷和顯示串列示範 ===")

ll = LinkedList()

print("建立測試串列:")
test_data = [10, 25, 30, 15, 40]
for value in test_data:
    ll.append(value)

print("\n=== 各種顯示方式 ===")

print("\n1️⃣ 簡單顯示:")
ll.display_simple()

print("\n2️⃣ 詳細顯示 (包含遍歷步驟):")
ll.display_detailed()

print("\n3️⃣ 顯示位置資訊:")
ll.display_with_positions()

print("\n4️⃣ 視覺化顯示:")
ll.display_visual()

print("\n=== 自訂遍歷功能 ===")

print("\n5️⃣ 使用回調函數遍歷:")
def print_info(data, position):
    print(f"   位置 {position}: 值 {data}, 平方 = {data**2}")

ll.traverse_with_callback(print_info)

print("\n6️⃣ 計算統計資訊:")
stats = ll.get_statistics()
for key, value in stats.items():
    print(f"   {key}: {value}")

print("\n=== 空串列測試 ===")
empty_ll = LinkedList()
print("\n7️⃣ 空串列的各種顯示:")
empty_ll.display_simple()
empty_ll.display_detailed()
empty_ll.display_visual()

print("\n📝 重要觀念:")
print("- 遍歷是鏈結串列的基礎操作,幾乎所有功能都需要遍歷")
print("- 遍歷模式:current = head; while current: ...; current = current.next")
print("- 時間複雜度:O(n) - 需要訪問每個節點一次")
print("- 空間複雜度:O(1) - 只需要一個 current 指標")

print("\n🔍 遍歷模板:")
print("""
def traverse(self):
    current = self.head          # 從頭開始
    while current is not None:   # 檢查是否到達末尾
        # 處理當前節點
        print(current.data)
        current = current.next   # 移動到下一個節點
""")

print("\n⚠️ 常見錯誤:")
print("- 忘記檢查 head 是否為 None")
print("- 忘記更新 current = current.next (造成無限迴圈)")
print("- 在遍歷過程中修改串列結構")

🎓 學習總結

我已經為你詳細介紹了Python鏈結串列的8個核心概念:

  1. 節點(Node) - 鏈結串列的基本組成單位
  2. 鏈結串列結構 - 了解head指標和基本架構
  3. 開頭新增節點 - 最快速的插入操作 O(1)
  4. 末尾新增節點 - 需要遍歷的插入操作 O(n)
  5. 指定位置新增 - 最靈活的插入操作 O(n)
  6. 刪除節點 - 按值或按位置刪除 O(n)
  7. 搜尋節點 - 查找特定值或位置 O(n)
  8. 遍歷顯示 - 所有操作的基礎

📚 學習建議

  1. 先理解再實作:確實理解每個概念的邏輯再看程式碼
  2. 畫圖練習:在紙上畫出節點和指標的變化過程 (可參考 LeetCode — 2. Add Two Numbers 中的圖)
  3. 逐步除錯:使用print語句追蹤程式執行過程
  4. 比較分析:對比鏈結串列與陣列的優缺點
  5. 實際應用:嘗試用鏈結串列解決實際問題 (可參考 LeetCode — 2. Add Two Numbers)