python链表——实现链表逆序的三种方式:就地逆序,递归,插入法

本文介绍了单链表逆序的三种方法,包括就地逆序、递归逆序和插入法逆序。详细阐述了每种方法的思路、代码实现及优缺点。三种方法时间复杂度均为O(N),就地逆序和插入法逆序性能较高,递归逆序代码逻辑简单但性能较低。
Python3.8

Python3.8

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

输入:1 -> 2 -> 3 ->4
输出:4 -> 3 -> 2 -> 1

一、就地逆序
思路:
1、引入外部操作节点的变量pre, cur, nex,分别代表前一个节点、当前节点、下一个节点。
2、单链表的每个节点只有一个指针,故对每个节点的指针进行2次操作,第1次指针操作,将当前节点指针cur.next值临时保存到nex,即nex = cur.next, 第2次指针操作,将当前的指针cur.next指向其前一个节点pre, 即cur.next = pre,这样就实现了对单个节点的操作。
3、操作节点的变量移动,cur指向下一个操作节点,即cur = nex,这样通过while循环即可实现对每个节点操作。
4、特殊情况:链表为空链表、链表为单节点,直接返回即可,无需逆序操作

代码如下:

def reverse(head):
    # 特殊情况:头节点为空或者为单节点,直接返回
    if head is None or head.next is None:
        return head
    else:
        # 移动cur到头节点
        cur = head
        # 操作当前节点指针, 2次操作
        nex = cur.next
        cur.next = None
        
        # 移动cur到下一个节点
        pre = cur
        cur = nex
        # 循环操作节点
        while cur.next:
            # 操作当前节点指针, 2次操作
            nex = cur.next
            cur.next = pre
            # 移动cur到下一个节点
            pre = cur
            cur = nex
        # 最后一个操作节点, 指针指向其前一个pre,同时将其设为头节点
        cur.next = pre
        head = cur
    return head

评价:链表每个节点遍历1次,故时间复杂度为O(N), 只引入3个外部变量作为临时存储,性能方面较高,不足之处,在于代码逻辑没有那么清晰明了,需要理解三个外部变量是如何移动的,2次指针操作是如何变化的。

二、递归逆序
思路:
1、首先将1 -> 2 -> 3 ->4变成1 -> 4-> 3 -> 2(其中2 -> 3 ->4变成4-> 3 -> 2,采用递归方式实现)
2、再将head头节点1移到尾巴,作为尾结点,由于上一个尾结点2,是原先的head.next,此时将2的next指针指向头节点,即head.next.next = head,然后尾结点指向空,即head.next = None
在这里插入图片描述
3、特殊情况:头节点为空或者只有1个节点

代码:

def recursiveReverse(head):
	#  头节点为空或者只有1个节点
    if head is None or head.next is None:
        return head
    else:
        # 先反转后边的节点:1->4->3->2,递归实现
        new_head = recursiveReverse(head.next)
        # 然后将head移动到节点head.next之后,2次指针操作
        head.next.next = head
        head.next = None
        # 参数为头结点,所以返回的为new_head新的头结点
        return new_head

评价:优点是代码逻辑比较简单,链表每个节点遍历1次,故时间复杂度为O(N), 不足在于,由于采用递归,每次的递归的值需要push到栈中,所以性能较低

三、插入法逆序
思路:
1、1 -> 2 -> 3 ->4变成2 -> 1 -> 3 ->4,再变成3 -> 2 -> 1 -> 4,最后4 -> 3 -> 2 -> 1
2、先操作头节点,2次指针操作,第一次赋值给外部变量cur=head.next, 由于头节点变为尾结点,即head.next=None
3、从第二个节点开始,每次都将遍历到的节点,插入到头节点前边,作为新的头节点,2次指针操作和头节点指针指定操作,即2次指针操作:nex=cur.next, cur.next=head, 指定头节点:head=cur
4、移动cur到下一个节点,即cur=nex
5、特殊情况:头节点为空,或者单个节点,直接返回
代码:

def insertReverse(head):
	# 特殊情况:头节点为空,或者只有单个节点
    if head is None or head.next is None:
        return
    # 操作头节点, 2次指针操作,头节点head.next赋值给cur, 由于头节点最终要成为尾结点,其指向为空
    cur = head.next
    head.next = None
    # 操作第二个及之后的节点,每次遍历到的节点都放到头节点处
    while cur:
        nex = cur.next
        cur.next = head
        head = cur
        cur = nex
    return head

评价:每个节点都遍历一次,时间复杂度为O(N),引入外部变量cur, nex作为临时存储,性能较高,代码逻辑方面,每个节点仍然是2次指针操作,以及操作对象的指针nex, cur的移动,与就地逆序类似,相对简单。

# 测试
link = LinkedList()
print("=========== before =============")
link.add(1)
link.add(2)
link.add(3)
link.add(4)
link.print_list()
print("=========== after ==============")
new_head = reverse(link.head)
while new_head:
    print(new_head.data)
    new_head = new_head.next
# 结果
=========== before =============
1
2
3
4
=========== after ==============
4
3
2
1

您可能感兴趣的与本文相关的镜像

Python3.8

Python3.8

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值