Python 算法详解:链表
一、什么是链表?(最通俗讲解)
1. 链表本质
链表是一种“链式存储”的线性数据结构。
- 数据不是连续存放
- 每个元素(节点)存:数据 + 下一个节点的地址
- 像一根链条,一环扣一环
2. 链表 vs 数组(必懂对比)
| 特性 | 数组(List) | 链表(LinkedList) |
|---|---|---|
| 存储方式 | 连续内存 | 分散内存 |
| 访问元素 | 快,直接下标访问 | 慢,要从头遍历 |
| 插入/删除 | 慢,要移动元素 | 快,只改地址指向 |
| 占用内存 | 小 | 大(存数据+地址) |
一句话记忆:
数组适合查,链表适合增删。
二、链表的基本结构
1. 节点(Node)
链表的最小单位,包含两部分:
- 数据域(val):存数据
- 指针域(next):存下一个节点的地址
2. 单链表节点代码(必须背会)
# 节点类
class ListNode:
def __init__(self, val=0, next=None):
self.val = val # 数据
self.next = next # 指向下一个节点
3. 单链表结构
头节点 → 节点1 → 节点2 → 节点3 → None
三、链表基本操作(增删改查 全图解+代码)
下面所有代码可直接运行,逐行带注释。
操作1:创建链表
# 创建节点
n1 = ListNode(10)
n2 = ListNode(20)
n3 = ListNode(30)
# 链接节点
n1.next = n2
n2.next = n3
# 头节点
head = n1
操作2:遍历链表(最常用)
# 遍历:从头走到尾
def traverse(head):
cur = head
while cur:
print(cur.val, end=" → ")
cur = cur.next
print("None")
# 调用
traverse(head)
输出:
10 → 20 → 30 → None
操作3:查找元素
def find(head, target):
cur = head
while cur:
if cur.val == target:
return True
cur = cur.next
return False
print(find(head, 20)) # True
操作4:尾部添加节点(尾插)
def add_tail(head, val):
new_node = ListNode(val)
# 如果链表为空
if not head:
return new_node
# 找到最后一个节点
cur = head
while cur.next:
cur = cur.next
cur.next = new_node
return head
head = add_tail(head, 40)
traverse(head) # 10→20→30→40→None
操作5:头部添加节点(头插)
def add_head(head, val):
new_node = ListNode(val)
new_node.next = head
return new_node
head = add_head(head, 5)
traverse(head) # 5→10→20→30→40→None
操作6:删除节点(重点!面试必考)
删除值为 target 的节点
def delete_node(head, target):
# 情况1:删头节点
if head and head.val == target:
return head.next
# 情况2:删中间/尾部节点
cur = head
while cur.next:
if cur.next.val == target:
cur.next = cur.next.next # 核心!跳过要删的节点
return head
cur = cur.next
return head
head = delete_node(head, 20)
traverse(head) # 5→10→30→40→None
✅ 删除核心:让前节点直接指向后节点,跳过被删节点。
操作7:修改节点值
def update_node(head, old_val, new_val):
cur = head
while cur:
if cur.val == old_val:
cur.val = new_val
return
cur = cur.next
update_node(head, 10, 100)
traverse(head) # 5→100→30→40→None
四、链表必考经典算法(面试/作业高频)
算法1:反转链表(最最最常考)
题目:
给你单链表的头节点 head,反转链表,并返回反转后的链表。
代码(三指针法)
def reverse_list(head):
pre = None
cur = head
while cur:
temp = cur.next # 保存下一个节点
cur.next = pre # 反转指向
pre = cur # pre 前移
cur = temp # cur 前移
return pre
调用
head = reverse_list(head)
traverse(head) # 40→30→100→5→None
算法2:求链表长度
def get_length(head):
count = 0
cur = head
while cur:
count +=1
cur = cur.next
return count
print(get_length(head)) # 4
算法3:查找倒数第k个节点
def find_kth_from_end(head, k):
fast = head
slow = head
# 快指针先走k步
for _ in range(k):
if not fast:
return None
fast = fast.next
# 一起走
while fast:
fast = fast.next
slow = slow.next
return slow.val
print(find_kth_from_end(head,2)) # 100
算法4:判断链表是否有环
def has_cycle(head):
slow = head
fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if slow == fast:
return True
return False
快慢指针法(龟兔赛跑)
五、单链表完整整合代码(可直接交作业)
# 节点类
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
# 遍历
def traverse(head):
cur = head
while cur:
print(cur.val, end=" → ")
cur = cur.next
print("None")
# 头插
def add_head(head, val):
new_node = ListNode(val)
new_node.next = head
return new_node
# 尾插
def add_tail(head, val):
new_node = ListNode(val)
if not head:
return new_node
cur = head
while cur.next:
cur = cur.next
cur.next = new_node
return head
# 删除
def delete(head, target):
if head and head.val == target:
return head.next
cur = head
while cur.next:
if cur.next.val == target:
cur.next = cur.next.next
return head
cur = cur.next
return head
# 反转
def reverse(head):
pre = None
cur = head
while cur:
temp = cur.next
cur.next = pre
pre = cur
cur = temp
return pre
# 测试
if __name__ == "__main__":
head = None
head = add_tail(head,1)
head = add_tail(head,2)
head = add_tail(head,3)
traverse(head)
head = reverse(head)
traverse(head)
六、重点总结
1. 链表核心
- 由节点组成
- 每个节点:数据 + next指针
- 不连续存储,增删快,查询慢
2. 必掌握操作
- 遍历
- 增(头插、尾插)
- 删(改指针指向)
- 改
- 查
3. 必考算法
- 反转链表
- 快慢指针(环、倒数第k个)
- 链表长度
- 删除节点

浙公网安备 33010602011771号