python单向链表逆序_python经典面试算法题1.1:如何实现链表的逆序

本题目摘自《Python程序员面试算法宝典》,我会每天做一道这本书上的题目,并分享出来,统一放在我博客内,收集在一个分类中。

1.1 如何实现链表的逆序

【腾讯笔试题】

难度系数:⭐⭐⭐

考察频率:⭐⭐⭐⭐

题目描述:

给定一个带头结点的单链表,请将其逆序。即如果单链表原来为 head -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7,那么逆序后变为 head -> 7 -> 6 -> 5 -> 4 -> 3 -> 2 -> 1。

解答

构造结点类和单链表类

class Node:

def __init__(self, data, next):

self.data = data

self.next = next

class SingleLink:

def __init__(self, head):

self.head = head

方法一:就地逆序(推荐,好理解)

主要思路:在遍历链表的时候,修改当前结点的指针域指向,让它指向它的前驱结点。

时间复杂度:O(n)

def reverse(link: SingleLink):

if link.head is None or link.head.next is None:

return None

cur = link.head.next # cur指向第一个结点

pre = link.head # pre指向头结点

while cur.next is not None: # 如果cur不是最后一个结点

ne = cur.next # ne记住当前结点的下一个结点

if pre != link.head: # 如果cur不是第一个结点

cur.next = pre # 把当前结点的next指向前一个结点

else:

cur.next = None

pre = cur # pre结点后移到当前结点

cur = ne # 当前结点后移一位

ne = ne.next # ne结点后移一位

# cur指向tail了

cur.next = pre # 当cur指向了最后一个结点,循环结束,把最后一个结点指向倒数第二个结点

link.head.next = cur # head指向最后一个结点,即cur

方法二:插入法(推荐,好理解)

主要思路:从链表的第二个结点开始,把遍历到的结点插入到头结点的后面,直到遍历结束。

时间复杂度:O(n)

def reverse2(link: SingleLink):

if link.head is None or link.head.next is None: # 空

return link.head

cur = link.head.next.next # 记住第二个结点

link.head.next.next = None # 第一个结点的指针从指向第二个结点变成None

while cur is not None: # 当第二个结点不是None的时候

next = cur.next # next等于第二个结点的next即第三个结点

cur.next = link.head.next # 第二个结点的next指向第一个结点

link.head.next = cur # head的next也从指向第一个结点变成指向第二个结点

cur = next # cur开始指向第三个结点, 如此循环下去

方法三:递归法(不推荐,算法实现难度大,需要额外的压栈和弹栈,有性能下降)

主要思路:先把除了第一个结点以外的结点逆序,接着把第一个结点添加到子链表的后面。

时间复杂度:O(n)

def RecursiveReverse(head):

# 如果链表为空,或者只有一个元素

if head is None or head.next is None:

return head

else:

# 反转后面的结点

newhead = RecursiveReverse(head.next)

# 把当前遍历的结点加到后面结点逆序后链表的尾部

head.next.next = head

head.next = None

return newhead

def Reverse(head):

if head is None:

return

first_node = head.next

newhead = RecursiveReverse(first_node)

# 将头结点指向逆序后链表的第一个结点

head.next = newhead

return newhead

测试

i = 1

tmp = Node(i, None)

head = Node(None, tmp)

while i < 8:

tmp.next = Node(i, None)

tmp = tmp.next

i += 1

print("正序是: ", end="")

cur = head

while cur.next is not None:

cur = cur.next

print(cur.data, end=" ")

print()

link1 = SingleLink(head)

reverse(link1)

print("逆序是: ", end="")

cur = link1.head

while cur.next is not None:

cur = cur.next

print(cur.data, end=" ")

# 输出:

正序是: 1 1 2 3 4 5 6 7

逆序是: 7 6 5 4 3 2 1 1

欢迎小伙伴们加入我创建的python交流群:625988679

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM4NzI3ODQ3,size_10,color_FFFFFF,t_70

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值