链表就像一列火车,每节车厢(节点)有两个部分:
在 Python 中,可以用类表示:
pythonclass ListNode:
def __init__(self, val=0, next=None):
self.val = val # 值
self.next = next # 指向下一个节点的指针
例如,链表 1 -> 2 -> 3
就是三个节点,每个的“钩子”连向下一个。
反转链表就是把所有“钩子”的方向调转。比如:
原链表:1 -> 2 -> 3 -> None 反转后:3 -> 2 -> 1 -> None
每个节点的“钩子”从指向下一个,变成指向前一个。
逐个节点调整指针方向,需要三个变量帮忙记录位置。
prev
:记录前一个节点,初始是空(None
)。current
:当前处理的节点,初始是头节点。next_node
:临时保存下一个节点,防止“钩子”断了找不到路。每次循环:
next_node = current.next
)current.next = prev
)prev
和 current
都往后移动一步当 current
为空时,prev
就是新头节点。
pythondef reverseList(head):
prev = None
current = head
while current:
next_node = current.next # 先记住下一个节点
current.next = prev # 反转指针
prev = current # prev 移到当前节点
current = next_node # current 移到下一个节点
return prev # 循环结束,prev 是新的头
反转 1 -> 2 -> 3
:
prev=None
, current=1
2
,1
指向 None
,prev=1
,current=2
3
,2
指向 1
,prev=2
,current=3
None
,3
指向 2
,prev=3
,current=None
结束循环。最终链表是 3 -> 2 -> 1
先让后面的节点反转好,再调整当前节点。
2 -> 3
,反转成 3 -> 2
)。1
的下一个节点 2
已经指向 None
,需要让 2
指向 1
,然后 1
指向 None
。pythondef reverseList(head):
if not head or not head.next: # 空或只有一个节点
return head
new_head = reverseList(head.next) # 先处理后面的节点
head.next.next = head # 让后面的节点指向自己
head.next = None # 自己的指针设为空
return new_head
反转 1 -> 2 -> 3
:
3
时返回,new_head=3
2
的递归层:让 2.next(3)
指向 2
,2
指向 None
,此时链表是 3 -> 2 -> None
1
的递归层:让 1.next(2)
指向 1
,1
指向 None
,最终链表是 3 -> 2 -> 1 -> None
方法 | 时间复杂度 | 空间复杂度 | 优点 | 缺点 |
---|---|---|---|---|
迭代法 | O(n) | O(1) | 效率高,适合长链表 | 逻辑稍复杂 |
递归法 | O(n) | O(n) | 代码简洁,易于理解 | 可能栈溢出,空间占用大 |
用辅助函数将链表转为列表,方便验证:
pythondef list_to_array(head):
res = []
while head:
res.append(head.val)
head = head.next
return res
# 测试
# 创建链表 1->2->3
head = ListNode(1, ListNode(2, ListNode(3)))
reversed_head = reverseList(head)
print(list_to_array(reversed_head)) # 输出 [3, 2, 1]
通过逐步调整指针方向,无论是迭代还是递归,最终都能实现链表的反转。理解指针的变化是关键!
本文作者:Dong
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC。本作品采用《知识共享署名-非商业性使用 4.0 国际许可协议》进行许可。您可以在非商业用途下自由转载和修改,但必须注明出处并提供原作者链接。 许可协议。转载请注明出处!