Remove Duplicates from Linked List Python

送分小仙女□ 提交于 2020-12-05 07:20:25

问题


I am running below code to remove duplicates from Linked List. But my code only prints linked List before removing duplicates. Once removeDup method is called, it does not print anything. Below is my code. Please tell me what am I missing.

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

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

    def insert(self, data):
        node = Node(data)
        node.next=self.head
        self.head = node

    def printl(self):
        current  = self.head
        while current:
            print current.data
            current= current.next

    def removeDups(self):
        current = self.head
        while current is not None:
            second = current.next
            while second:
                if second.data == current.data:
                    current.next = second.next.next

                second = second.next
            current = current.next
#        l.printl()


l= LinkedList()
l.insert(15)
l.insert(14)
l.insert(16)
l.insert(15)
l.insert(15)
l.insert(14)
l.insert(18)
l.insert(159)
l.insert(12)
l.insert(10)
l.insert(15)
l.insert(14)

l.printl()
print "==============="

l.removeDups()
l.printl()

回答1:


Your logic for removing the duplicated items you find is not right. It causes you to cut out all the items between the first occurrence of a value and a point past its last occurrence. For your example list, that results in a single item, 14 being printed after the deduplication runs (it cuts from just after the first value to the end, though it makes some smaller cuts along the way too).

Here's a fixed version of your removeDups method.

def removeDups(self):
    current = second = self.head
    while current is not None:
        while second.next is not None:   # check second.next here rather than second
            if second.next.data == current.data:   # check second.next.data, not second.data
                second.next = second.next.next   # cut second.next out of the list
            else:
                second = second.next   # put this line in an else, to avoid skipping items
        current = second = current.next

The main change is that second points to the node before the second node we're actually interested in checking. We do all our work on second.next. We need to keep the reference to second so we can easily cut second.next out of the list. Doing it this way requires that we don't advance second if we've cut out a node, so the second = second.next line needs to be in an else clause.

Since current and second always start with the same value after each update to current, I changed the logic to assign both of them in a single statement. It would work fine the original way, I just think this way looks nicer.




回答2:


I think it is confusing to use the "second" variable.

def removeDups(self):
    current = self.head
    while current: #First loop
        while current.next and current.data == current.next.data: #Second loop
            current.next = current.next.next #Deletion
        current = current.next

You start at the head of the list and for each node in your list until you hit the None at the end (while current) you enter another loop. That loops checks to make sure there is a next node (while current.next) and if that next node has the same data as the current node (current.data == current.next.data). Each time this second loop is true, it means we have a duplicate. The next line (current.next = current.next.next) is what does the actual deletion. It also conveniently updates current.next to the next node in the list that we want to compare so that the second loop can immediately check again to see if we have another duplicate. Once that second loop has found and deleted all the duplicates for that particular node, we will drop down to the next line (current = current.next), update our current node to the next one and start checking that node for duplicates.




回答3:


We can use a list or dictionary to check whether the item inserted is already there or not

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

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

  def append(self,data):
    new_Node=Node(data)
    if self.head is None:
      self.head=new_Node
      return
    last_node=self.head
    while last_node.next:
      last_node=last_node.next
    last_node.next=new_Node

  def printing(self):
    current_node=self.head
    while current_node:
      print(current_node.data)
      current_node=current_node.next

  def remove_dup(self):
    curr=self.head
    glist=[]                        #list to store the values
    while curr:
      if curr.data in glist:        #checking the value already exists in list
        prev.next=curr.next
      else:
        glist.append(curr.data)
        prev=curr
      curr=curr.next

llist=LinkedList()
llist.append(1)
llist.append(6)
llist.append(1)
llist.append(4)
llist.append(2)
llist.append(2)
llist.append(4)
llist.remove_dup()
llist.printing()



回答4:


This is how removeDuplicates function should be written:

class node:
    def __init__(self):
        self.data = None
        self.next = None
class Linked_List:
    def __init__(self):
        self.head = None
    def get_head(self):
        return self.head
    def insert(self, data):
        if self.head == None:
            self.head = node()
            self.head.data = data
        else:
            new_node = node()
            new_node.data = data
            new_node.next = None
            temp = self.head
            while(temp.next):
                temp=temp.next
            temp.next = new_node
    def printlist(self):
        temp = self.head
        while temp!=None:
            print(temp.data, end=" ")
            temp= temp.next

def removeDuplicates(head):
    current = head
    element_list = []
    prev = None
    while (current is not None):
        if current.data not in element_list:
            element_list.append(current.data)
            prev = current
            current = current.next
        else:
            prev.next = current.next
            current = current.next


if __name__ == '__main__':
    values_list = [[5,2,2,4], [2,2,2,2,2]]
    t = len(values_list)
    for index in range(t):
        list1 = Linked_List()
        for i in values_list[index]:
            list1.insert(i)
        print('Input:')
        list1.printlist()
        print()
        removeDuplicates(list1.head)
        print('Output')
        list1.printlist()
        print('')

It removes duplicate nodes from sorted/unsorted singly linked list




回答5:


you can use an additional data structure to hold the unique values(e.g. a list)

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


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

    def insert_node(self, data):
        new_node = Node(data)
        if self.head is None:
            self.head = new_node
        else:
            new_node.next = self.head
            self.head = new_node

    def remove_dups(self):
        uniques = []
        prev = None
        curr = self.head
        while curr is not None:
            if curr.data in uniques:
                prev.next = curr.next
            else:
                uniques.append(curr.data)
                prev = curr
            curr = curr.next

    def print_list(self):
        output = ""
        tmp = self.head
        while tmp is not None:
            output += str(tmp.data) + " "
            tmp = tmp.next
        print(output)

`



来源:https://stackoverflow.com/questions/42728271/remove-duplicates-from-linked-list-python

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!