Reverse the Linked List using Recursion - python

I am using recursion to reverse the linked list but not getting the result. Whenever I am using the following code for the input [1,2,3,4,5,6,-1], it shows me the result [1->None]. I am not getting where I am making the mistake. Please help me.
class Node:
def __init__(self, data):
self.data = data
self.next = None
def takeInput():
inputList = [int(ele) for ele in input().split()]
head = None
for i in inputList:
if i == -1:
break
newNode = Node(i)
if head is None:
head = newNode
tail = newNode
else:
tail.next = newNode
tail = newNode
return head
def printLL(head):
while head is not None:
print(str(head.data) + "->", end="")
head = head.next
print("None")
return
def reverseLL(head):
if head is None or head.next is None:
return head
rest = reverseLL(head.next)
head.next.next = head
head.next = None
return rest
head = takeInput()
printLL(head)
reverseLL(head)
printLL(head)

The problem is in the main code: you're not taking the value returned by the reverseLL function, which is the new head. You should do:
head = reverseLL(head)

Related

I am trying to print the elements of linked list after adding it but it doesn't seem to work

I am trying to show the items in my linked list after inserting them with the function Add, and view function to print but it doesn't seem to work.
class Node():
def __init__(self,value):
self.value = value
self.next = None
class Linked_List():
def __init__(self):
self.head = None
self.tail = None
def Add(self,value):
if(self.head == None):
n = Node(value)
if(self.head == None):
self.head = n
else:
self.tail.next = n
self.tail = n
def view(head):
curr = head
while (curr):
print(curr.value,"-->")
curr = curr.next
newlist = Linked_List()
newlist.Add(5)
newlist.Add(6)
newlist.Add(56)
view(newlist.head)
It only shows the first element 5 and doesn't show the rest. I can't seem to understand the reason even if I have done acc. to the algorithm?
If head is not Null, Add doesn't do anything, which even the most rudimentary debugger would have made clear.

Delete last node in linked list

I am implementing deletion of last node in linked list using Python. Below is my code:
class Node:
def __init__(self, key):
self.key = key
self.next = None
def printList(head):
curr = head
while curr != None:
print(curr.key, end=" ")
curr = curr.next
def deleteLastNode(head):
if head == None:
return None
temp = head
# Iterating till the last Node
while temp.next != None:
temp = temp.next
temp = None
return head
# Driver code
head = Node(10)
head.next = Node(20)
head.next.next = Node(30)
head = deleteLastNode(head)
printList(head)
However, in output I'm still getting the complete linked list.
10 20 30
How is it printing 30 when the last node is already set to temp = None?
Well, your linked list is:
10 -> 20 -> 30
^head
Your iteration:
10 -> 20 -> 30
^head ^temp
Then when you do temp = None, just means(you just assign None to temp):
10 -> 20 -> 30 None
^head ^temp
A correct way is when you iterate on 20, do temp.next = None to remove the reference to the last node. So your code might be:
class Node:
def __init__(self, key):
self.key = key
self.next = None
def printList(head):
curr = head
while curr != None:
print(curr.key, end=" ")
curr = curr.next
def deleteLastNode(head):
if head == None:
return None
temp = head
# Iterating till the last Node
while temp.next.next != None:
temp = temp.next
temp.next = None
return head
# Driver code
head = Node(10)
head.next = Node(20)
head.next.next = Node(30)
head = deleteLastNode(head)
printList(head)
This code would work when your linked list contain at least two elements. When there is only one element, this will raise exception. I would recommend you use a dummy head node which next point to the real head node.
#Another way of solving
class Node:
def __init__(self, key):
self.key = key
self.next = None
def printList(head):
curr = head
while curr != None:
print(curr.key, end=" ")
curr = curr.next
def deleteLastNode(head):
if head == None:
return None
temp = head
prev=None #creating the value of previous element
# Iterating till the last Node
while temp.next != None:
prev=temp #updating for every iteration
temp = temp.next
prev.next = None #returning as NONE value
return head
# Driver code
head = Node(10)
head.next = Node(20)
head.next.next = Node(30)
head = deleteLastNode(head)
printList(head)

Why I can't create a linked list with a circle?

I am trying to create a linkedlist with a infinite circle like this 0->1->2->3->4->5-**>2**->3->4->5-**>2**->3->4->5-> ........., below is my code:
class node():
def __init__(self, val):
self.val = val
self.nextNode = None
def __repr__(self):
return "%s" % self.val
class linkedList():
def __init__(self):
self.head = None
def addNode(self, nodeVal):
newNode = node(nodeVal)
if self.head is None:
self.head = newNode
else:
tmp = self.head
while tmp.nextNode is not None:
tmp = tmp.nextNode
tmp.nextNode = newNode
def linkNode(self, node):
if self.head is None:
raise Exception("list can't be None")
tmp = self.head
while tmp.nextNode is not None:
tmp = tmp.nextNode
tmp.nextNode = node
def __repr__(self):
tmp = self.head
val = []
while tmp is not None:
val.append(tmp.val)
tmp = tmp.nextNode
return "vals are %s" % val
s = linkedList()
head = node(0)
node1 = node(1)
node2 = node(2)
node3 = node(3)
node4 = node(4)
node5 = node(5)
s.addNode(head)
s.addNode(node1)
s.addNode(node2)
s.addNode(node3)
s.addNode(node4)
s.addNode(node5)
s.linkNode(node2)
print(s)
But the output is this: vals are [0, 1, 2, 3, 4, 5, 2] which is not a circle.
As your method addNode expects a value, and will create a node for it, you should not call it with a node as argument.
So without altering your class methods, your main code could be as below. BTW, I find s a bad name for a list -- it is often used for a string -- so I named it lst instead:
lst = linkedList()
lst.addNode(0)
lst.addNode(1)
lst.addNode(2)
lst.addNode(3)
lst.addNode(4)
lst.addNode(5)
lst.linkNode(lst.next.next)
print(lst)
Not related, but here are some ways to improve your class:
as addNode each time needs to traverse the whole list, it might be good for your linked list to maintain a reference to the tail node. That way you can append a new node at the end in constant time.
addNode could also return the newly added node, so you can use that later for your call to linkNode
Here is how your code would look after implementing those ideas:
def __init__(self):
self.head = None
self.tail = None
def addNode(self, nodeVal):
newNode = node(nodeVal)
if self.head is None:
self.head = newNode
else:
self.tail.next = newNode
self.tail = newNode
return newNode
def linkNode(self, node):
if self.head is None:
raise Exception("list can't be None")
self.tail.next = node
# Main code
lst = linkedList()
lst.addNode(0)
lst.addNode(1)
backref = lst.addNode(2)
lst.addNode(3)
lst.addNode(4)
lst.addNode(5)
lst.linkNode(backref)
print(lst)
It is happening because in addNode you are creating a new node by doing
newNode = node(nodeVal)
which means when you later pass node2 to linkNode it is still a node with nextNode=None as create by the class Node
Just remove that line and you are good to go.
A small detail is needed, then it should work as you intend.
Replace your line s.linkNode(node2) with s.linknode(s.head.nextNode.nextNode)
Then to print the x first elements in the cycle use the following:
tmp = s.head
for i in range(x):
print(tmp.val)
tmp = tmp.nextNode
Note don't do print(s), as that will do an infinite loop in the cycle
The reason for the previous not working, is that you have in the function addNode() the following newNode = node(nodeVal) so it creates new nodes with no connection to the list.

inserting a node at tail python

I'm trying to insert a node at the tail but my list keeps just saving the last value
If I try to insert 1,5,7 at the head and 9 at tail..I only see 9 when I print it out
class Node:
def __init__(self,val,next=None)
self.val = val
self.next = next
head = None
def insert(val, pos = 'h')
global head
if head == None:
newNode = Node(val)
newNode.next = None
head = newNode
elif pos == 'h':
newNode = Node(val)
newNode.next = head
head = newNode
elif pos == 't':
newNode = Node(val)
newNode.next = None
#stuck here
while(head != None):
head = head.next
head = newNode
When adding a tail node, use a copy of head and when you reach the tail node, add the new node to it's '.next':
# stuck here
tail = head
while(tail.next is not None):
tail = tail.next
tail.next = newNode
In your example, you change the global value of head to point to the new node you just added.
Two errors here I think. One is you're replacing the global head (which needs to stay the same if you're adding at the tail). Use a local variable for the loop. Second is you're replacing the head itself by the new node instead of its .next field.
In your code there is a no connection between head and tails. Change yours code like this.
elif pos == 't':
newNode = Node(val)
head.next = newNode
newNode.next = None
and you can remove below part
#stuck here
while(head != None):
head = head.next
head = newNode
There are just so many things about your implementation which are not recommended/frowned upon. For instance, you don't need to use a global variable for head.
class Node:
def __init__(self, val):
self.val = val
self.next = None
def insert_head(head, val):
node = Node(val)
node.next = head
head = node
return head
def insert_tail(head, val):
if head is None:
return Node(val)
head.next = insert_tail(head.next, val)
return head
head = insert_head(None, 1)
head = insert_head(head, 5)
head = insert_head(head, 7)
head = insert_tail(head, 9)
Here's an implementation for example which provides the same functionality. To insert at head we simply create a new Node with the given value, point it's next element to the object pointed by head and then make head point to this node instead.
For inserting at tail we use an elegant recursive implementation. Both functions work even when the head node provided is None.
Why separate into two functions? Because typically you want your function to just perform a single well defined task. If a function is getting too complex you should break it down into smaller functions (again which do one thing and do it well). Newcomers often write functions with complex behaviors depending on some argument provided but that doesn't help with the readability, debugging, or performance of the function for the most part.
you can use a class like this:
class Node:
def __init__(self, val, next=None):
self.val = val
self.next = next
head = None
def insert(val, pos='h'):
global head
if head is None:
newNode = Node(val)
newNode.next = None
head = newNode
elif pos == 'h':
newNode = Node(val)
newNode.next = head
head = newNode
elif pos == 't':
newNode = Node(val)
head.next = newNode
newNode.next = None

LinkedList AttributeError: 'NoneType' object has no attribute 'data'

I'm working on the Codewars Kata on linkedLists, and keep getting the error AttributeError: 'NoneType' object has no attribute 'data'
class Node(object):
def __init__(self, data):
self.data = data
self.next = None`
def push(head, data):
if data == None: return
new_node = Node(data)
new_node.next = head
head = new_node
def build_one_two_three():
head = None
push(head, 3)
push(head, 2)
push(head, 1)
return head
I thought using the if data == None would fix the problem but it didn't. Any suggestions would be greatly appreciated.
The the line head = new_node in your push function is replacing the local reference that head is pointing to, not the data that head refers to in your build_one_two_three function. Try having push return head, and updating your build_one_two_three where each push updates the referece: head = push(head,1), etc.
I guess you are looking for something in the lines of:
class Node(object):
def __init__(self, data):
self.data = data
self.next = None
def push(head, data):
if data == None: return
new_node = Node(data)
new_node.next = head
head = new_node
return head
def build_one_two_three():
head = None
head = push(head, 3)
head = push(head, 2)
head = push(head, 1)
return head
# Just to pretty-print the linked list.
def pp(head):
res = ""
node = head
while node != None:
res += "%s -> " % node.data
node = node.next
res += "None"
print res
if __name__ == "__main__":
head = build_one_two_three()
pp(head)
The problem is that you are overwriting the reference to head every time you push a new node.

Categories

Resources