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
周濡墨的沙龍
17會員
119內容數
有別於未付費的文章,專題區的文章偏向愛情短篇小說,較有戲劇性,篇幅也會較長;未付費文章會偏向極短篇小說,並且以類似散文的手法寫作
周濡墨的沙龍的其他內容
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
2025 vocus 推出最受矚目的活動之一——《開箱你的美好生活》,我們跟著創作者一起「開箱」各種故事、景點、餐廳、超值好物⋯⋯甚至那些讓人會心一笑的生活小廢物;這次活動不僅送出了許多獎勵,也反映了「內容有價」——創作不只是分享、紀錄,也能用各種不同形式變現、帶來實際收入。
Thumbnail
2025 vocus 推出最受矚目的活動之一——《開箱你的美好生活》,我們跟著創作者一起「開箱」各種故事、景點、餐廳、超值好物⋯⋯甚至那些讓人會心一笑的生活小廢物;這次活動不僅送出了許多獎勵,也反映了「內容有價」——創作不只是分享、紀錄,也能用各種不同形式變現、帶來實際收入。
Thumbnail
嗨!歡迎來到 vocus vocus 方格子是台灣最大的內容創作與知識變現平台,並且計畫持續拓展東南亞等等國際市場。我們致力於打造讓創作者能夠自由發表、累積影響力並獲得實質收益的創作生態圈!「創作至上」是我們的核心價值,我們致力於透過平台功能與服務,賦予創作者更多的可能。 vocus 平台匯聚了
Thumbnail
嗨!歡迎來到 vocus vocus 方格子是台灣最大的內容創作與知識變現平台,並且計畫持續拓展東南亞等等國際市場。我們致力於打造讓創作者能夠自由發表、累積影響力並獲得實質收益的創作生態圈!「創作至上」是我們的核心價值,我們致力於透過平台功能與服務,賦予創作者更多的可能。 vocus 平台匯聚了
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