【问题标题】:Singly linked list infinite loop when sharing elements between lists in PythonPython中列表之间共享元素时的单链表无限循环
【发布时间】:2018-10-22 20:09:52
【问题描述】:

我使用 Python 3.6 实现了一个链表,链表本身运行良好,但问题是当我尝试创建以下示例时:

3 -> 1 -> 5 -> 9 ->
                   7 -> 2
          4 -> 6 ->

这意味着我有 2 个链表,并且在某一点上它们共享相同的元素 (7,2),我的链表代码如下:

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

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

    def append(self,new_element):
        current = self.head
        if current:
            while current.next:
                current = current.next
            current.next = new_element
        else:   
            self.head = new_element

    def print_linked(self):
        current = self.head
        while current:
            print(current.value, end=" ")
            current = current.next

e1 = Element(3)
e2 = Element(1)
e3 = Element(5)
e4 = Element(9)

e1p = Element(4)
e2p = Element(6)

e1s = Element(7)
e2s = Element(2)

# Start setting up a LinkedList
ll = LinkedList(e1)
ll.append(e2)
ll.append(e3)
ll.append(e4)
ll.append(e1s)
ll.append(e2s)

l2 = LinkedList(e1p)
l2.append(e2p)
l2.append(e1s)
l2.append(e2s)

当我尝试打印任何链表时,程序总是在最后一个元素处进入无限循环,在我尝试共享同一个元素时发生。

3 1 5 9 7 2 2 2 2 2 2 2 [...] 

我错过了什么吗?帮助表示赞赏。谢谢

【问题讨论】:

    标签: python-3.x oop infinite-loop singly-linked-list


    【解决方案1】:

    让我们回顾一下:

    ll.append(e2)
    ll.append(e3)
    ll.append(e4)
    ll.append(e1s)
    ll.append(e2s)
    

    在这段代码运行后,最后一项 (e2s) 的内部状态是否指向任何地方。

    然后:

    l2.append(e2p)
    l2.append(e1s)
    l2.append(e2s)
    

    这使得最后一项指向自身(l2.append(e2s) 附加而不考虑循环)。您迭代整个列表并附加该项目即使它已经存在

    由于状态是节点内部的 (Element),您可能有两种选择:

    1. 不共享状态(复制)
    2. 检查节点是否存在,不允许它在列表中重复

    如果有重复项,您可以引发错误:

    def append(self,new_element):
        current = self.head
        if current is new_element:
            raise ValueError('can not duplicate node %s on list' % new_element)
        if current:
            while current.next:
                current = current.next
            current.next = new_element
        else:   
            self.head = new_element
    

    【讨论】:

    • 我试图制作对象的深层副本,但我想使用“is”比较两个对象是否相同,重点是检查两个列表是否共享相同的元素(对象不是值)。有可能吗?
    • 如果你复制的不是is(身份)不会是True
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-04
    • 2017-05-30
    • 1970-01-01
    • 2017-04-25
    • 2018-01-21
    • 1970-01-01
    • 2012-09-05
    相关资源
    最近更新 更多