链表翻转

曾经在面试时候被问到单链表的翻转,今天又重新总结了一下。对于链表的遍历有两种,一种是线性的,比如forwhile,另一种是非线性的,也就是递归。

对于翻转单链表的线性遍历有两种思路,一种是创建一个新链表,头结点插入法,另一种是就地反转法。前者理解相对容易一些,先说第一种方法,再说第二种。

单链表翻转

在重新说一下题目的定义:
在这里插入图片描述
定义一个链表的单结点:

class ListNode:
	def __init__(self, x):
		self.value = x
		self.next = None

创建新链表,头结点插入法

顾名思义,就是新创建一个链表,遍历要翻转的链表,把元素作为新链表的头元素插入。
在这里插入图片描述
在这里插入图片描述
定义两个指针,pCur代表要插入到新链表的结点。pNext是用来记录要翻转列表的。下面的代码对应上面4个步骤。

# 1. pNext是一个临时结点,记录下一个要插入到新链表的结点
pNext = pCur.next
# 2. 把pCur结点插入到新链表的dummy后边
pCur.next = dummy.next
# 3. 调整新链表的dummy结点的指向
dummy.next = pCur
# 更新pCur
pCur = pNext

经过四步之后:
在这里插入图片描述

总结:

  • 需要创建一个新链表,两个指针,其中包括一个临时指针,4行代码
  • 本质:链表的遍历和链表的插入。对于新创建的链表来讲,是一个不断插入头结点的操作。

就地反转法

在这里插入图片描述
需要两个指针,prev代表要反转的结点的前一个结点,pCur代表要反转的结点。

# 1. prev连接下一次需要反转的节点
反转节点pCur
纠正头结点dummy的指向
pCur指向下一次要反转的节点
prev.next = pCur.next
# 2. 反转结点
pCur.next = dummy.next
# 3. 调整dummy的指向
dummy.next = pCur
# 4. 更新pCur
pCur = prev.next

反转之后的链表,上面的数字,与上图的数字是对应的关系,更方便看不同步骤操作后得到的链接:
在这里插入图片描述
就地反转法的完整代码:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def reverseList(self, head: ListNode) -> ListNode:
        if not head:
        	return head
	    dummy = ListNode(-1)
	    # 加上dummy之后,链表的head就是dummy结点了,再用head不好理解
	    dummy.next = head
	    #创建prev指针,在要反转结点的前面一个结点
	    prev = head
	    # 创建pcur指针,要反转的结点
	    pcur = prev.next
	    while pcur:
	        # prev指向下一个要反转的结点
	        prev.next = pcur.next
	        # 反转结点
	        pcur.next = dummy.next
	        # 调整dummy结点
	        dummy.next = pcur
	        # 更新要反转的结点
	        pcur = prev.next
	    return dummy.next
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值