I tried program to delete node from linked list recursively. My program is given below
class node:
def __init__(self, data=None):
self.data = data
self.next = None
class linkedList:
def __init__(self):
self.head=None
def printList(self):
cur = self.head
while(cur != None):
print(cur.data,end="->")
cur=cur.next
print("null")
def push(self,dat):
newNode = node(dat)
temp = self.head
self.head = newNode
newNode.next = temp
@staticmethod
def dnr(head, key):
if head is not None:
if head.data == key:
head=head.next
return head
if head is not None:
head.next = linkedList.dnr(head.next, key)
return head
return head
if __name__ == '__main__':
ll=linkedList()
ll.push(3)
ll.push(6)
ll.push(9)
ll.push(12)
ll.push(15)
ll.printList()
print("*******")
# ll.head = linkedList.dnr(ll.head,2)
linkedList.dnr(ll.head,9)
ll.printList()
The problem with this is that this does not work for first element.To make it work for first element I have to call the function like this
ll.head = linkedList.dnr(ll.head,2)
second thing is that I wanted my function to call this way
ll.dnr(2)
please tell me how to create a recursive function to delete node in linked list in python
CodePudding user response:
I rewrote your code:
class node:
def __init__(self, data=None):
self.data = data
self.next = None
class linkedList:
def __init__(self):
self.__head=None
def printList(self):
cur = self.__head
while(cur != None):
print(cur.data,end="->")
cur=cur.next
print("null")
def push(self,dat):
newNode = node(dat)
temp = self.__head
self.__head = newNode
newNode.next = temp
@staticmethod
def __dnr(head, key):
if head is None:
return head
if head.data == key:
head = head.next
return head
head.next = linkedList.__dnr(head.next, key)
return head
@staticmethod
def dnr(listObj, key):
if listObj is None or listObj.__head is None:
return listObj
if listObj.__head.data == key:
listObj.__head = listObj.__head
listObj.__head = linkedList.__dnr(listObj.__head, key)
def deleteKey(self, key):
linkedList.dnr(self, key)
if __name__ == '__main__':
ll=linkedList()
ll.push(3)
ll.push(6)
ll.push(9)
ll.push(12)
ll.push(15)
ll.printList()
print("*******")
linkedList.dnr(ll, 9)
ll.deleteKey(12)
ll.printList()
I made head
variable inside linkedList
class private, it's not smart to give access outer world to class core components. And class core components should never leak to the outer world because if it's that not used properly that can cause errors. So I rewrote your dnr
function and now it's more clear and it doesn't return head
object which is core component of linkedList
class. Now dnr
function just check if passed listObj
is valid and check if head
is that node that should be deleted. After that it calls private static __dnr
function to delete node with given key
. Function deleteKey
can be called like this ll.deleteKey(12)
, that is what you wanted.
Giving core component accessible through outer world is like giving bank customer access to a bank vault. Not everybody will try to steal money from it, but there will be someone who will try.
If you don't understand private variables follow this link.
CodePudding user response:
I wanted my function to call this way
ll.dnr(2)
Then you need to define an instance method. Your static function can serve a purpose, but as you noted, you really need to assign its return value back to your list's head
attribute to be sure it also works when the original head node is removed. With your static method you cannot avoid this overhead, since that method has no knowledge about your linkedList instance.
You can achieve what you want simply by adding an instance method, that will rely on the existing static method and will deal with this assignment back to the instance's head
attribute.
Add this to your linkedList
class:
def remove(self, key):
self.head = linkedList.dnr(self.head, key)
Now in your main program you can do:
ll.remove(15)
Side note: you don't need the second if head is not None:
check in your static method, as this condition will always be true when the execution reaches that point in your code. Just do the assignment to head.next
unconditionally.
Addendum
If you want dnr
itself to become an instance method (without addition of a remove
method), then you need to temporarily cut off the head node from the list (even if you want to keep it), recur, and then conditionally add that cut-off node again (if it's key is not the one to delete).
It would look like this:
def dnr(self, key):
head = self.head
if head:
self.head = head.next # Skip
if head.data != key: # Need to restore it
self.dnr(key) # But first look further...
head.next = self.head # Prefix the removed node
self.head = head # ...and make it the head again
You would call like:
ll.dnr(15)