Link list in python

更新 發佈閱讀 60 分鐘

前言

為了完成 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)


如果喜歡這篇文章的會請點個分享家案讚吧 (please~~ please~~🥹


留言
avatar-img
留言分享你的想法!
avatar-img
周濡墨的沙龍
18會員
120內容數
有別於未付費的文章,專題區的文章偏向愛情短篇小說,較有戲劇性,篇幅也會較長;未付費文章會偏向極短篇小說,並且以類似散文的手法寫作
周濡墨的沙龍的其他內容
2025/08/15
Soup Servings - LeetCode Description You have two soups, A and B, each starting with n mL. On every turn, one of the following four serving operatio
2025/08/15
Soup Servings - LeetCode Description You have two soups, A and B, each starting with n mL. On every turn, one of the following four serving operatio
2025/08/06
將水果放入籃子 - LeetCode --- Fruit Into Baskets - LeetCode Description You are visiting a farm that has a single row of fruit trees arranged from......
2025/08/06
將水果放入籃子 - LeetCode --- Fruit Into Baskets - LeetCode Description You are visiting a farm that has a single row of fruit trees arranged from......
2025/08/01
Given an integer numRows, return the first numRows of Pascal's triangle. In Pascal's triangle, each number is the sum of the two numbers directly.....
Thumbnail
2025/08/01
Given an integer numRows, return the first numRows of Pascal's triangle. In Pascal's triangle, each number is the sum of the two numbers directly.....
Thumbnail
看更多
你可能也想看
Thumbnail
想在蝦皮雙11買到最划算?這篇文章將分享作者精選的蝦皮高CP值商品,包含HERAN禾聯冷氣、HITACHI日立冰箱、DJI無線麥克風、FUJIFILM拍立得,並提供蝦皮雙11優惠券領取教學、省錢技巧,以及蝦皮分潤計畫介紹,讓你買得開心、省得多!
Thumbnail
想在蝦皮雙11買到最划算?這篇文章將分享作者精選的蝦皮高CP值商品,包含HERAN禾聯冷氣、HITACHI日立冰箱、DJI無線麥克風、FUJIFILM拍立得,並提供蝦皮雙11優惠券領取教學、省錢技巧,以及蝦皮分潤計畫介紹,讓你買得開心、省得多!
Thumbnail
2025 蝦皮 1111 購物節又來了!分享三大必買原因:全站 $0 起免運、多重優惠疊加、便利取貨。 此外,推薦兩款高 CP 值的即食拉麵(無印良品即食迷你拉麵、維力迷你麵野菜拉麵),並分享如何透過「蝦皮分潤計畫」放大效益,開心購物之餘還能獲得額外收益!
Thumbnail
2025 蝦皮 1111 購物節又來了!分享三大必買原因:全站 $0 起免運、多重優惠疊加、便利取貨。 此外,推薦兩款高 CP 值的即食拉麵(無印良品即食迷你拉麵、維力迷你麵野菜拉麵),並分享如何透過「蝦皮分潤計畫」放大效益,開心購物之餘還能獲得額外收益!
Thumbnail
介紹如何用assign函數在Python中建立新欄位
Thumbnail
介紹如何用assign函數在Python中建立新欄位
Thumbnail
Python語法包括條件語句、迴圈、函數和變數的使用。條件語句如if、elif和else用於進行條件判斷,for和while是兩種主要的迴圈,def用於定義函數。變數可以被賦予數字或字符串,並可使用類型提示來指定變數的類型。註解可以是單行或多行,並可用於解釋函數或類的用途和作用。
Thumbnail
Python語法包括條件語句、迴圈、函數和變數的使用。條件語句如if、elif和else用於進行條件判斷,for和while是兩種主要的迴圈,def用於定義函數。變數可以被賦予數字或字符串,並可使用類型提示來指定變數的類型。註解可以是單行或多行,並可用於解釋函數或類的用途和作用。
Thumbnail
在程式中,了解資料型態是相當重要的。 為什麽? 因為許多error,常常都是因為資料型態不正確所導致的。 舉個例子,在python中: a = 1 + 2 print(a) 結果就是3 a = = "1"+"2" print(a) 結果就是12 是不是差很多? 所以今天我來介
Thumbnail
在程式中,了解資料型態是相當重要的。 為什麽? 因為許多error,常常都是因為資料型態不正確所導致的。 舉個例子,在python中: a = 1 + 2 print(a) 結果就是3 a = = "1"+"2" print(a) 結果就是12 是不是差很多? 所以今天我來介
Thumbnail
參加Leetcode的30 Days of Pandas挑戰,除了是學習的機會,更是練習熟悉pandas功能的機會。文章分享了挑戰簡介、題目描述、關鍵技術以及參加挑戰的心得。適合新手學習pandas,也可提升熟練度。
Thumbnail
參加Leetcode的30 Days of Pandas挑戰,除了是學習的機會,更是練習熟悉pandas功能的機會。文章分享了挑戰簡介、題目描述、關鍵技術以及參加挑戰的心得。適合新手學習pandas,也可提升熟練度。
Thumbnail
題目敘述 題目會給我們一棵二元搜索樹的根結點root,還有一個指定的目標值val。 要求我們找出在樹中對應到目標值val的節點,假如找不到,請回傳null( null在Python就是None)。 題目的原文敘述 測試範例 Example 1: Input: root = [4,2,
Thumbnail
題目敘述 題目會給我們一棵二元搜索樹的根結點root,還有一個指定的目標值val。 要求我們找出在樹中對應到目標值val的節點,假如找不到,請回傳null( null在Python就是None)。 題目的原文敘述 測試範例 Example 1: Input: root = [4,2,
Thumbnail
如何用Python為某欄做分類,例如:判斷分數是否及格 
Thumbnail
如何用Python為某欄做分類,例如:判斷分數是否及格 
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News