为什么我的链接列表没有删除多个重复项?

时间:2018-02-02 01:45:50

标签: python class linked-list duplicates nodes

我有以下代码:

class LinkedList:

  def __init__(self):
    self.head = None

我将remove_duplicate()函数添加到此LinkedList类中,该类除去列表中的第一个实例之外的任何重复项。

  def remove_duplicate(self, value):
    prev = None
    curr = self.head
    count = 0

    while curr:
        if curr.get_value() == value:
            count += 1
            if count > 1 :
                prev.set_next_node(curr.get_next_node())

        prev = curr
        curr = curr.get_next_node()

在我的主要功能中,我正在进行这些系列的调用。

linked_list = LinkedList()
linked_list.add("john")
linked_list.add("john")
linked_list.add("john")
linked_list.remove_duplicate("john")
print(linked_list)

我希望得到

['john']

但我得到了

['john', 'john']

为什么我的代码不会像我们的那样删除重复项?

P.S。我之前写的节点代码

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

    def get_value(self):
        return self.value

    def get_next_node(self):
        return self.next_node

    def set_value(self, new_value):
        self.value = new_value

    def set_next_node(self, new_next):
        self.next_node = new_next

1 个答案:

答案 0 :(得分:0)

是的,我认为第一次运行循环时,您将curr设置为head,找到与value匹配的内容,因此请增加计数,然后将curr移至{ {1}}并将第二个元素设为prev

现在,您找到一个匹配项并从列表中删除curr。这会将下一个元素附加到currprev.next)。但是,您还没有更改head的内容,因此当您离开curr时,您会将if替换为您尝试删除的prev

因此,您尝试在第一个元素之后删除的下一个元素,您不能这样做 - 即任何序列到两个重复,第二个元素会在您返回到正确的链之前被忽略。

我发现拼写更容易理解:

curr

作为一种解决方案,您需要在找到双倍时以及所有其他时间稍微不同时对待,可能如下所示:

# self.head
#     |
# [ node1 ].next > [ node2 ].next > [ node3 ].next > None
#     |                |                |
#   val1             val2             val3

prev = None, curr = node1
prev = curr # prev = node1 
curr = curr.next # curr = node2 

prev = node1, curr = node2
# here we change the contents of one of the nodes (node1.next)
prev.next = curr.next # node1.next = node3
# but here we are then placing the `disposed of` node as the previous one
prev = curr # prev = node2
curr = curr.next # curr = curr3

# prev is incorrect here
prev = node2, curr = node3
# here, when theres a match to delete, we then delete the link from the wrong node
prev.next = curr.next # node2.next = None
prev = curr # prev = node 3
curr = curr.next # curr = None

我已经对其余代码进行了一些猜测,但如果这是以

运行的话
def remove_duplicate(self, value):
    prev = None
    curr = self.head
    count = 0

    while curr:
        # this is just to see which Nodes weren't being removed.
        if curr.value.startswith(value):
            count += 1
            # if this is false, your original update is still used
            if count > 1:
                # here, the first thing to do is get rid of curr,
                curr = curr.get_next_node()
                # and then attach the new curr to the previous Node
                prev.set_next_node(curr)
                # and restart the loop
                continue
        # this is done for any Node which isn't a multiple of value
        prev = curr
        curr = curr.get_next_node()

你得到了

linked_list = LinkedList()
linked_list.add("john1")
linked_list.add("john2")
linked_list.add("fred")
linked_list.add("john3")
linked_list.add("john4")
linked_list.add("alice")
linked_list.add("john5")
linked_list.remove_duplicate("john")
print(linked_list)