python实现反转链表
方法一:直接调换箭头
思路
需要用到三个指针:前驱、当前节点、后继
代码实现
class Solution:
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
if head == None or head.next == None:
return head
else:
p = head # 前驱
q = head.next # q当前结点
p.next = None # 避免闭环
r = None
while q:
r = q.next # 后继
q.next = p # q指向p
p = q # p向后移动一位
q = r # q向后移动一位
return p
注意!
需要首先将头结点后的指针置空,避免出现闭环。
- 为什么后面的不需要,只有头结点之后的指针需要单独处理呢?
因为后面的在q指向p的时候,由于是单链表,所以q之后的指针已经自动删除了。 - 为什么while只需要判断q,而不是q.next?
当使用q作为终止条件时,p最后指向尾结点,q指向空(尾结点的next为空),此时返回p,缩短了代码长度。
方法二:递归
思路
调换箭头的方向,尾结点成为新的头节点,返回头节点≈返回反转链表
代码实现
class Solution:
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
if head == None:
node = head # 链表为空,直接输出
elif head.next == None:
node = head # 递归追溯到尾结点 ## 只执行一次,即追溯到尾结点
else:
node = self.reverseList(head.next)
head.next.next = head # 调换箭头顺序
head.next = None # 避免链表闭环 ## 这两行反复执行
return node # 返回尾(头)结点,即返回整个链表
注意!
代码中的5/6行只执行一次,退出递归时反复执行9/10行,调换箭头顺序。
返回尾结点(反转链表的头节点)即返回新的反转链表
方法三:头插法创建单链表
思路
遍历链表,每次创建一个新节点,这个结点的值等于当前结点的值,指针指向上一个结点。
代码实现
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
node = None # 初始化指针
while head: # 当前结点不为空
node = ListNode(val = head.val, next = node) # 指针指向上一个结点
head = head.next # 顺序遍历
return node # 返回创建的新链表
注意:node(指针)需要初始化为空,因为原链表的头结点反转后是尾结点,尾结点指针指向空。