【问题标题】:Why doesn't my linked list remove multiple duplicates?为什么我的链表没有删除多个重复项?
【发布时间】:2018-02-02 01:45:50
【问题描述】:

我有以下代码:

class LinkedList:

  def __init__(self):
    self.head = None

我在这个 LinkedList 类中添加了 remove_duplicate() 函数,该函数删除除了列表中的第一个实例之外的所有重复项。

  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']

为什么我的代码没有按预期删除重复项?

附言有我之前写的Node代码

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

【问题讨论】:

  • 您能否将代码提供给您的set_next_node 函数?
  • 我更新了我的节点代码

标签: python class linked-list duplicates nodes


【解决方案1】:

对,我认为你的循环第一次运行时,你将curr 设置为head,找到与value 的匹配项,所以增加计数然后将curr 移动到prev 并获得第二个元素curr.

现在,您找到匹配项并从列表中删除 curr。这会将下一个元素附加到prev.next(即head)。但是你没有改变 curr 是什么,所以当你离开 if 时,你会用你试图删除的 curr 替换 prev

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

我发现拼写出来更容易理解:

# 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)

你得到

~$>./linked_list.py 
['john1', 'fred', 'alice']

【讨论】:

  • 那你认为我需要尝试另一种方法来解决这个问题吗?我该如何实现它?
  • 不,它只是稍微重新排列 if 语句,并使用 continue。
  • @G.Lee159 只是出于兴趣,这为您解决了吗?
  • @G.Lee159 如果已解决,您也可以将其标记为已接受,以便下一个人也知道。
猜你喜欢
  • 1970-01-01
  • 2011-08-18
  • 1970-01-01
  • 2020-05-23
  • 2020-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多