简体   繁体   English

在python中反转链接列表时无法访问链接列表的下一个节点

[英]unable to access next node for Linked List while reversing a Linked List in python

I am a bit new to python and I have seen the correct solutions to the reversing the linkedlist problem but I wanted to know why my solution does not work. 我对python有点陌生,我已经看到了解决反向链接列表问题的正确解决方案,但是我想知道为什么我的解决方案不起作用。 In particular, reverse function stays inside the while loop for the code below because of "new_list.head.next=prev" line 特别地,由于“ new_list.head.next = prev”这一行,反向函数停留在以下代码的while循环内

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

class LinkedList:
    def __init__(self):
        self.head = None

    def append(self, value):
        if self.head is None:
            self.head = Node(value)
            return

        node = self.head
        while node.next:
            node = node.next

        node.next = Node(value)

    def __iter__(self):
        node = self.head
        while node:
            yield node.value
            node = node.next

    def __repr__(self):
        return str([v for v in self])

def reverse(linked_list):
    new_list = LinkedList()
    if linked_list is None:
        return new_list
    node = linked_list.head
    new_list.head = node 
    while node.next:
        prev = node
        node = node.next
        new_list.head = node
        new_list.head.next = prev
    return new_list   

if __name__ == "__main__":
    a = LinkedList()
    b = [1,2,3,4,5]
    for item in b:
        a.append(item)
    print a
    c = reverse(a) 
    print c

If you tag your question with Python3 please make sure it runs in python 3. 如果您使用Python3标记问题,请确保它在python 3中运行。

The reason is because you are mixing up points and creating an infinite loop. 原因是因为您混淆了点并创建了无限循环。 Print the value and it may help you find the bug. 打印该value ,它可以帮助您发现错误。 I am going to use the values to point out the issue. 我将使用这些值指出问题。

    while node.next:
        # First node that comes in value = 1
        print(node.value) #
        prev = node # prev = 1
        node = node.next # node = 2
        new_list.head = node # You are setting the head = 2 (i.e. head = node.next)
        new_list.head.next = prev # You are setting next of head = 1 (i.e. head.next = node.next.next)
        # however this also set node.next.next = 1
        # So going into the next loop: node.value = 2 and node.next.value = 1

Because of this pointer confusion you are forever looping between your first and second node. 由于指针混乱,您将永远在第一个节点和第二个节点之间循环。

This is how your reverse can look: 这是您的reverse情况:

def reverse(linked_list):
    new_list = LinkedList()
    if linked_list is None:
        return new_list
    node = linked_list.head
    new_list.head = Node(node.value)
    while node.next:
        node = node.next
        prev_head = new_list.head
        new_list.head = Node(node.value)
        new_list.head.next = prev_head
    return new_list

With it I got desired output of print c : [5, 4, 3, 2, 1] 有了它,我得到了所需的print c输出print c[5, 4, 3, 2, 1]

General advise: create new Node instead of assignment to node in initial list. 一般建议:创建新节点,而不是分配给初始列表中的节点。

It's a little easier to reason about this (at least to me) if you think about two references: 如果您想到两个引用,那么对此(至少对我来说)要容易一点:

• One to the remaining part of the original list you haven't seen •您未曾看到的原始清单的其余部分之一
• One to the head of the new list •新清单的首位

At each iteration move the remaining up and set the old remaining to the head of the new list. 在每次迭代时,将剩余部分向上移动,并将旧的剩余部分设置为新列表的开头。 Order is important here — as you've seen it's easy to accidentally change next on two different variables that are pointing the same node if you're not careful: 顺序在这里很重要-如您所见,如果不小心,很容易意外地在指向同一节点的两个不同变量上进行下一步更改:

def reverse(linked_list):
    new_list = LinkedList()

    if linked_list is None:
        return new_list

    remaining = linked_list.head

    while remaining:
        prev_head = new_list.head       # the old head becomes the first link
        new_list.head = remaining       # new head becomese the first remaining
        remaining = remaining.next      # move remaing one up the chain
        new_list.head.next = prev_head  # point the new head to the previous   
    return new_list   

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM