1. 为什么链表操作总让人头晕?
每次看到链表相关的题目,指针就开始在眼前跳舞。明明在纸上画得好好的,一写代码就各种空指针异常。这感觉就像在玩一个永远对不齐的俄罗斯方块——新节点要么插不进去,要么把整个链表结构搞得一团糟。
我刚开始刷LeetCode时,707题的设计链表让我卡了整整两天。后来发现,问题的根源在于没有真正理解指针操作的底层逻辑。单向链表每个节点只认识它的下一个邻居,而双向链表虽然多了个前驱指针,但边界条件的处理反而更复杂。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 链表基础:从内存模型说起
2.1 物理存储 vs 逻辑结构
链表在内存中是非连续存储的,就像散落在城市各处的快递柜。每个柜子(节点)里放着包裹(数据)和下一个柜子的取件码(指针)。与数组这种"集体宿舍"不同,链表更像是通过GPS定位的连锁便利店。
python复制class ListNode:
def __init__(self, val=0):
self.val = val # 当前节点数据
self.next = None # 指向下一节点的指针
2.2 单/双向链表性能对比
| 操作类型 | 单向链表 | 双向链表 |
|---|---|---|
| 插入删除(已知前驱) | O(1) | O(1) |
| 随机访问 | O(n) | O(n) |
| 反向遍历 | 不支持 | O(1) per step |
| 内存占用 | 较小 | 多一个指针的空间 |
实际工程中,Java的LinkedList和Redis的List都是双向实现,而Linux内核的任务队列多用单向链表
3. Dummy Node:链表操作的瑞士军刀
3.1 头节点删除的陷阱
直接看个血泪案例:要删除链表里所有值为6的节点
python复制# 错误示范
def removeElements(head, val):
while head and head.val == val: # 处理头
