【问题标题】:Reverse a linked list while preserving the original order在保留原始顺序的同时反转链表
【发布时间】:2020-01-13 14:19:45
【问题描述】:

我想将链表head 反转为一个新的反转点赞列表。我可以反转列表,但这样做,原始列表 head 也会受到影响,head.next 变为 None

def reverse(head): 
    prev = None
    current = head 
    while(current is not None): 
        next = current.next
        current.next = prev 
        prev = current 
        current = next 

最初:head :- 1-->2-->3-->4-->None

反转后: 头:-1-->None 上一页 :- 4-->3-->2-->1-->None

我基本上希望head是1-->2-->3-->4-->None

这里是链表反转的代码:-

class Node:
    def __init__(self, data):
        self.data = data
        self.next = None

def print_llist(head):
    while (head):
        print(head.data)
        head = head.next

def reverse(head):
    prev = None
    current = head
    while (current is not None):
        next = current.next
        current.next = prev
        prev = current
        current = next
    return prev


llist = Node(1)
second = Node(2)
third = Node(3)
fourth = Node(4)

llist.next = second
second.next = third
third.next = fourth

# print original list
print("Original:")
print_llist(llist)

# print reversed list
print("Reversed")
print_llist(reverse(llist))

# print original list
print("Original:")
print_llist(llist)

输出:-

Original:
1
2
3
4
Reversed
4
3
2
1
Original:
1

预期输出:-

Original:
1
2
3
4
Reversed
4
3
2
1
Original:
1
2
3
4

【问题讨论】:

  • 你能把你的链表代码贴出来吗?
  • 嗨,@MasonCaiby 感谢您的回复。我已经用代码更新了问题。

标签: python linked-list singly-linked-list


【解决方案1】:

在while循环结束后添加current.next=prev。并将您的 while 循环条件更改为 while(current.next is not None):

从您的函数中返回 current 而不是 prev。另外,添加一个条件来查看head 是否为None

所以你的函数变成了以下

def reverse(head):
     if head is None:
         return head
     prev=None
     current=head
     while(current.next is not None):
             next=current.next
             current.next=prev
             prev=current
             current=next
     current.next = prev
     return current

【讨论】:

  • 不就返回None吗?因为当currentNone 时while 循环结束。
【解决方案2】:

首先写Node 这样你就可以在构造函数中传递data next -

class Node:
  def __init__(self, data, next = None):
    self.data = data
    self.next = next

这让我们可以写 -

mylist = Node(1, Node(2, Node(3, Node(4))))

您将看到我们如何在reverse 中使用Node 的第二个参数-

def reverse(llist):
  def loop (r, node):
    if node is None:
      return r
    else:
      return loop (Node(node.data, r), node.next)
  return loop (None, llist)

注意我们如何构造一个新的Node,而不是使用node.data = ...node.next = ... 修改node。递归可以优雅地表达解决方案,无需改变原始输入。

我们也可以使用递归将链表转换为字符串 -

def to_str(node):
  if node is None:
    return "None"
  else:
    return f"{node.data} -> {to_str(node.next)}"

print(to_str(mylist))
# 1 -> 2 -> 3 -> 4 -> None

让我们验证reverse不会改变原始链表-

mylist = Node(1, Node(2, Node(3, Node(4))))

revlist = reverse(mylist)

print(to_str(mylist))
# 1 -> 2 -> 3 -> 4 -> None

print(to_str(revlist))
# 4 -> 3 -> 2 -> 1 -> None

print(to_str(mylist))
# 1 -> 2 -> 3 -> 4 -> None

与您的问题不太相关,但您可能认为直接在Node 上实现__str__ 更“pythonic”,这样您就可以使用print 输出链接列表-

class Node:
  def __init__(self, data, next = None):
    self.data = data
    self.next = next

  def __str__(self):
    return f"{self.data} -> {self.next}"

现在预计用户不会手动使用to_strprint_llist -

mylist = Node(1, Node(2, Node(3, Node(4))))

print(mylist)
# 1 -> 2 -> 3 -> 4 -> None

print(reverse(mylist))
# 4 -> 3 -> 2 -> 1 -> None

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-30
    • 1970-01-01
    • 2023-04-05
    • 2018-09-09
    • 2010-09-18
    相关资源
    最近更新 更多