pythonrecursionlinked-listpass-by-referencecall-by-value

Python function calling on linked list, call by value/call by reference


below is the code for print a linked list

 def printlinkedlist(root):
  if root==None:
    return
  print(root.data)
  printlinkedlist(root.next)

Suppose the linked list contain

1-2-3-4-5-6-7-8

by calling printlinkedlist(root) --------->it give out put as------>1-2-3-4-5-6-7-8

Now, i call another function

def linkedlist2(root):
  if root==None:
    return
  print(root.data)
  if root.next==None:
    root.data=50
    return
  linkedlist2(root.next)

Which basically make the last element value as 50. when i called the function printlinkedlist(root) it produce 1-2-3-4-5-6-7-50

doubt 1: since the value changed in orginal root, whether the root is passed by value or passed by reference?

Let hope it is passed by reference, if so

def linkedlist3(root):
  if root==None:
    return
  print(root.data)
  if root.next==None:
    root=None
    return
  linkedlist3(root.next)

which basically make the last node as None.ie, the 1-2-3-4-5-6-7-50 output should be like 1-2-3-4-5-6-7 (since 50 is maked as None) when call linkedlist(root). this is not what happend. it produce the same previous output, which is 1-2-3-4-5-6-7-50.

Can some one please explain why my desired output not produced and whether it is happening as call by value or call by reference???.


Solution

  • It is a reference that is passed by value (i.e. it's similar to passing a pointer in C).

    When you set root.next you are changing the value of next for the node that root refers to, and so the list changes at that node. When you set root itself, you are only modifying the reference that was passed in, not the underlying value that it refers to, and so the list is unaffected.

    If you want to remove the last node of a linked list, you need to set the next of the second-to-last node to None. Something like:

    def pop_last(root):
        if root is None or root.next is None:
            raise IndexError("can't pop from list with len < 2")
        if root.next.next is None:
            val = root.next.data
            root.next = None
            return val
        return pop_last(root.next)