2

I have been working on linked lists in Python. I was able to create nodes, link nodes, and add new nodes, but I am really stuck at deleting the node, especially the case when the element present in the node matches with the header (first node in list) where the root pointer is pointing to it.

I have written a condition to check that the input element matches with the element in the header node and, if found, I have changed the root pointer to the next node pointer but am still not able to delete the node.

Below is the function I have created to delete the node:

import copy
class Node:
      def __init__(self,data=None):
        self.data=data
        self.pointer=None

class Llist:
      def __init__(self):
        self.rootpointer=None

      def addlist(self,newdata):
        self.newdata=newdata
        node4=Node(newdata)
        node4.pointer=self.rootpointer
        self.rootpointer=node4

      def Dispaylist(self):
        self.cpyrootpointer=copy.deepcopy(self.rootpointer)
        while self.cpyrootpointer is not None :
          print (self.cpyrootpointer.data)
          self.cpyrootpointer=self.cpyrootpointer.pointer

      def removeitem(self,item):
        self.item=item
        self.cpyrootpointerr=copy.deepcopy(self.rootpointer)
        curr=self.cpyrootpointerr
        while self.cpyrootpointerr is not None:
            if(self.cpyrootpointerr.data==item):
              self.cpyrootpointerr=curr.pointer
              break




linkedlist=Llist()
linkedlist.rootpointer=Node('A')
linkedlist.rootpointer.pointer=Node('B')
linkedlist.rootpointer.pointer.pointer=Node('C')

linkedlist.addlist('D')
linkedlist.Dispaylist()

linkedlist.addlist('E')
print('break')
linkedlist.Dispaylist()
linkedlist.removeitem('E')
linkedlist.Dispaylist()

I have E-->D--->A-->B-->C in the list. What I want is D--->A-->B-->C after I call the removeitem() function, but I am getting E-->D--->A-->B-->C again.

aschultz
  • 1,658
  • 3
  • 20
  • 30
jacee
  • 41
  • 6
  • you are inserting at begging? i think in linked list we insert at last. – Jainil Patel Aug 09 '19 at 21:02
  • why `self.item=item`? and what's the point of `self.cpyrootpointerr=copy.deepcopy(self.rootpointer)`??? – juanpa.arrivillaga Aug 09 '19 at 21:04
  • @juanpa.arrivillaga self.item=item is for the element which needs to be deleted , if that element is found in root header Node then that node should be deleted and I have self.cpyrootpointerr=copy.deepcopy(self.rootpointer) because as I call the function for first time the pointer keeps traversing from left most to right most till the pointer is pointing towards None and when we call the function again , since it is pointing to None it wont display anything and hence I made a copy of pointer and Used it to traverse through the list – jacee Aug 09 '19 at 22:08
  • why are you creating an instance variable? None of this makes a lot of sense, you only need a `.root` attribute, and it never has to be deepcopied. Also, not really relevant, but *python doesn't have pointers*. You copied the entire object being referenced by that name – juanpa.arrivillaga Aug 09 '19 at 22:13
  • @juanpa.arrivillaga I am totally new to python and I am really sorry if it does not make much sense , could you give me a sample code of what you are exactly trying to say so I could understand please? – jacee Aug 09 '19 at 22:19
  • So for example, in `addList`, you create an instance variable: `self.newdata=newdata`. Why make that an instance variable? What purpose does it serve? You are simply polluting the object's namespace, it isn't necessary. While it isn't always true that instance variables should be created only in `__init__`, generally, for something like a linked list, they should. Again, a linked list really only needs a `self.root` attribute. You can add a `self.tail` and even a `self.size` for constant-time length lookup (at the cost of a bit of memory) – juanpa.arrivillaga Aug 09 '19 at 22:33
  • @juanpa.arrivillaga Okay , I kinda get what you are trying to say of using Instance Variables , could you help me with the delete function as I have been struggling with that for a while – jacee Aug 09 '19 at 22:41
  • @jacee for starters, you never actually change the root. You just manipulate a copy – juanpa.arrivillaga Aug 09 '19 at 22:44

2 Answers2

1

You are not changing the root pointer, you are changing a copy. "self.cpyrootpointerr=curr.pointer" should be "self.rootpointer = curr.pointer". Be aware that this only handles the case where the first item on the list is being deleted.

lcongdon
  • 36
  • 4
  • That really helped , thank you so much .I am really confused about when to work with with copy and when to work with Original , If you could help me understand , that would be great – jacee Aug 09 '19 at 23:01
  • @jacee well in this case **you never need the copy to begin with** – juanpa.arrivillaga Aug 09 '19 at 23:13
  • @juanpa.arrivillaga I understood that I did wrong ,that is why I clearly asked when to use what ? So i won't repeat in future but you are again pointing out that I should not need a copy here , I get that and I am really glad you are trying to help here but I am still lost if you don't explain me why to use copy and why is not needed in this case ? – jacee Aug 09 '19 at 23:18
  • @jacee it's hard for me to understand what you intend with the copy. You need a copy when you actually want to copy things, you want two distinct objects that have the *same value*, in other words. In this case, you are merely trying to mutate a particular object. Creating a copy of that object, then mutating the copy, will render those mutations ineffective in the original. It's almost the exact *opposite* of what you want. – juanpa.arrivillaga Aug 09 '19 at 23:20
  • @juanpa.arrivillaga thanks for the information, I need to work more on this to get a good idea , Keep helping starters like me :) – jacee Aug 09 '19 at 23:28
0

See delete function in this post

class LinkedList(Node):
    ...
    def delete(self,value):
        temp = self.__head
        while temp!=None:
            if temp.value == value and temp == self.__head:
                self.__head = temp.ref
                del temp
                self.__count -= 1
                break
            elif temp.ref != None and temp.ref.value == value:
                temp_ref = temp.ref.ref
                del temp.ref
                self.__count -= 1
                temp.ref = temp_ref
                break
            temp = temp.ref

Er. Harsh Rathore
  • 758
  • 1
  • 7
  • 21
  • what's the point of `del temp`? it does nothing useful, as far as I can tell – juanpa.arrivillaga Aug 09 '19 at 23:13
  • `del temp` will free up the memory occupied by the node referenced by temp – Er. Harsh Rathore Aug 09 '19 at 23:15
  • It deletes that name, which will be deleted when the function terminates anyway (which it will because you break out of the loop in that case and the function ends). It is completely unnecessary. Neither of these things will *necessarily* lead to the Node object being reclaimed, that depends on its reference count. – juanpa.arrivillaga Aug 09 '19 at 23:17
  • @juanpa.arrivillaga nope! see the elif block I have assigned the next nodes ref to previous node after deleting the current node. If I wrote `del temp` then you are right but it is `del temp.ref` so please revise again – Er. Harsh Rathore Aug 09 '19 at 23:21
  • What does the elif block have to do with you writing `del temp` in the if block? Again, it is completely pointless, because that variable *will always be deleted when the function terminates anyway* – juanpa.arrivillaga Aug 09 '19 at 23:22
  • @juanpa.arrivillaga so, why del operator is there in python – Er. Harsh Rathore Aug 09 '19 at 23:28
  • @juanpa.arrivillaga and yes deletion from the head mean what switching the head to the second element. I thing no you should delete the memory occupied by the head node then switching the head to next node will your second task – Er. Harsh Rathore Aug 09 '19 at 23:32
  • **`del`** does **not delete memory/objects**. Python != C. `del` deletes a *name*. That's it's purpose. You seem to fundamentally misunderstand what `del` does, and CPython's memory management. You can imagine that at the end of all your functions, there are lines doing `del x; del y` for all the local variables. It's completely unnecessary, it will *already happen*. – juanpa.arrivillaga Aug 09 '19 at 23:35
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/197749/discussion-between-er-harsh-rathore-and-juanpa-arrivillaga). – Er. Harsh Rathore Aug 10 '19 at 00:07