前言
為了完成 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️⃣:在開頭新增節點
在串列開頭插入新節點是最簡單的操作,只需要:
- 建立新節點
- 新節點的 next 指向原本的 head
- 更新 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️⃣:在末尾新增節點
在串列末尾插入新節點需要找到最後一個節點,步驟:
- 建立新節點
- 如果串列為空,新節點成為 head
- 否則遍歷到最後一個節點,將其 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️⃣:在指定位置新增節點
在指定位置插入節點需要先移動到正確位置,步驟:
- 檢查位置是否有效
- 如果是位置0,等同於開頭插入
- 否則移動到插入位置的前一個節點
- 調整指標連結
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個核心概念:
- 節點(Node) - 鏈結串列的基本組成單位
- 鏈結串列結構 - 了解head指標和基本架構
- 開頭新增節點 - 最快速的插入操作 O(1)
- 末尾新增節點 - 需要遍歷的插入操作 O(n)
- 指定位置新增 - 最靈活的插入操作 O(n)
- 刪除節點 - 按值或按位置刪除 O(n)
- 搜尋節點 - 查找特定值或位置 O(n)
- 遍歷顯示 - 所有操作的基礎
📚 學習建議
- 先理解再實作:確實理解每個概念的邏輯再看程式碼
- 畫圖練習:在紙上畫出節點和指標的變化過程 (可參考下一篇 LeetCode -- 2. Add Two Numbers 中的圖)
- 逐步除錯:使用print語句追蹤程式執行過程
- 比較分析:對比鏈結串列與陣列的優缺點
- 實際應用:嘗試用鏈結串列解決實際問題 (可參考下一篇 LeetCode -- 2. Add Two Numbers)
如果喜歡這篇文章的會請點個分享家案讚吧 (please~~ please~~🥹