Home > database >  Passing values between two doubly linked lists in python
Passing values between two doubly linked lists in python

Time:01-11

I would like to pass value of my doubly linked list into a new, empty doubly linked list so that I can work on sorting and removing nodes in DLL without changing my core one.

Here's how it looks like:

dllToBeSorted = DoublyLinkedList()
dllToBeSorted = newDoublyLinkedList      #contents of newDoublyLinkedList here: 0 3 0 4 1 1 2 3
dllToBeSorted.sortList()
dllToBeSorted.removeDuplicates()
dllToBeSorted.display()                  #contents of dllToBeSorted here: 0 1 2 3 4 
newDoublyLinkedList.display()            #contents of newDoublyLinkedList here: 0 1 2 3 4 

But when I try to display values, bot of DLLs are the same. I don't know why this is happening, because this method works on usual variables (strings, ints and whatnot) but here for some reason it changes bot of my DLLs.

If it helps I'm putting below my whole executable code:

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


class DoublyLinkedList:
    def __init__(self):
        self.head = None
        self.start_node = None

    def insertToEmptyList(self, data):
        if self.start_node is None:
            new_node = Node(data)
            self.start_node = new_node

    def insertToEnd(self, data):
        if self.start_node is None:
            new_node = Node(data)
            self.start_node = new_node
            return
        n = self.start_node
        while n.next is not None:
            n = n.next
        new_node = Node(data)
        n.next = new_node
        new_node.prev = n

    def display(self):
        if self.start_node is None:
            print(" ")
            return
        else:
            n = self.start_node
            while n is not None:
                print(n.item, end=" ")
                n = n.next
            print("\n")

    def searchNode(self, data):
        if self.start_node is None:
            print("0")
            return
        else:
            n = self.start_node
            counter = 0
            while n is not None:
                if n.item == data:
                    counter  = 1
                n = n.next
            print(counter)

    def sortList(self):
        if self.start_node is not None:
            n = self.start_node
            while n.next is not None:
                index = n.next
                while index is not None:
                    if n.item > index.item:
                        temp = n.item
                        n.item = index.item
                        index.item = temp
                    index = index.next
                n = n.next

    def removeDuplicates(self):
        if self.start_node is not None:
            n = self.start_node
            while n is not None:
                index = n.next
                while index is not None:
                    if n.item == index.item:
                        temp = index
                        index.prev.next = index.next
                        if index.next is not None:
                            index.next.prev = index.prev
                        temp = None
                    index = index.next
                n = n.next

newDoublyLinkedList = DoublyLinkedList()
newDoublyLinkedList.insertToEnd(0)
newDoublyLinkedList.insertToEnd(3)
newDoublyLinkedList.insertToEnd(0)
newDoublyLinkedList.insertToEnd(4)
newDoublyLinkedList.insertToEnd(1)
newDoublyLinkedList.insertToEnd(1)
newDoublyLinkedList.insertToEnd(2)
newDoublyLinkedList.insertToEnd(3)
    
dllToBeSorted = DoublyLinkedList()
dllToBeSorted = newDoublyLinkedList      #contents of newDoublyLinkedList here: 0 3 0 4 1 1 2 3
dllToBeSorted.sortList()
dllToBeSorted.removeDuplicates()
dllToBeSorted.display()                  #contents of dllToBeSorted here: 0 1 2 3 4 
newDoublyLinkedList.display()            #contents of newDoublyLinkedList here: 0 1 2 3 4 

Edit: copied the code in a way that is fully executable

CodePudding user response:

This is because you are working on 2 different variables that point to the same data structure (https://www.geeksforgeeks.org/copy-python-deep-copy-shallow-copy/). Overriding copy in DoublyLinkedList should do the trick.

def __copy__(self):
    newList = DoublyLinkedList()
    # add all data from self to newList
    return newList

So your code would become:

dllToBeSorted = DoublyLinkedList()
dllToBeSorted = newDoublyLinkedList.copy()      #contents of newDoublyLinkedList here: 0 3 0 4 1 1 2 3
dllToBeSorted.sortList()
dllToBeSorted.removeDuplicates()
dllToBeSorted.display()                  #contents of dllToBeSorted here: 0 1 2 3 4 
newDoublyLinkedList.display()            #contents of newDoublyLinkedList here: 0 1 2 3 4 

CodePudding user response:

To understand your problem you will have to understand this small example.

my_data = [1,2,3]

def my_func(data):
    data.append(100)
    return data

print("You sent: ", my_data)

# Calling my function to add an element to the list and returning the result
result_data = my_func(my_data)

print("I changed it to: ", result_data)
print("Your original input: ", my_data)

We didn't expected the list passed as an argument to get modified but it got modified. For detailed answer you can read this article

So basically you are performing all the sorting actions on your original lists/items behind the scenes and you are getting same outputs for your display functions.

You can use python lists copy function (or create an implementation for your class)

to make my example work as expected you can call the function my_func using

# result_data = my_func(my_data) Old way
result_data = my_func( my_data.copy() )
  •  Tags:  
  • Related