Home > Software engineering >  When we assign a LinkedList (list1) to another (l1), changes made to list1 are not reflected in l1.
When we assign a LinkedList (list1) to another (l1), changes made to list1 are not reflected in l1.

Time:07-28

Following is the method I wrote for merging two Linked-Lists (MergeTwoLists(ListNode list1, ListNode list2)). Following is the entire program:

using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LinkedList
{
     public class ListNode
    {
        public int val;
        public ListNode next;
        public ListNode(int val = 0, ListNode next = null)
        {
            this.val = val;
            this.next = next;
        }
     }


    internal class Program
    {
        static void Main(string[] args)
        {
            ListNode list1= new ListNode(1, new ListNode(2, new ListNode(4, null)));//Heap -> list1 is a pointer to an object on the heap (list1 pointer itself is on the stack).
            ListNode list2 = new ListNode(1, new ListNode(3, new ListNode(4, null)));//Heap -> list2 is a pointer to an object on the heap (list2 pointer itself is on the stack).
            ListNode list3 = MergeTwoLists(list1,list2);//list3 points to Heap. list3 is also a pointer to an object on the heap. And initially, that object on Heap = null. The list3 pointer (variable), is itself on the stack.
        }

        public static ListNode MergeTwoLists(ListNode list1, ListNode list2) //pass by Reference
        {
            if (list1 == null)
                return list2;
            else if (list2 == null)
                return list1;
            ListNode l3 = new ListNode(0,null),l1=list1,l2=list2;
            ListNode l4 = l3;
            while (list1 != null && list2 != null)//list1 = 1->2->4->null
            {                               //list2 = 1->3->4->null
                if (list1.val <= list2.val)
                {
                    l4.next = list1;
                    list1 = list1.next;//when we are first time in the while loop, list1 now = 2->4->null but l1 (which = list1) still = 1->2->4->null!!
                }
                else
                {
                    l4.next = list2;
                    list2 = list2.next;
                }
                l4 = l4.next;
            }
            l4.next=list1==null?list2:list1;
            return l3.next;
        }
    }
}

As shown above (as commented above), when we enter the while loop in the method MergeTwoLists the first time - list1 = list1.next. And list1 now = 2->4->null (list1 was 1->2->4->null originally). But, l1 = list1, so the changes in list1 should be reflected in l1. And l1 should now also = 2->4->null (initially, both l1 = list1 = 1->2->4->null). But, l1 now still = 1->2->4->null whereas list1 now = 2->4->null. Why is it so? Am I missing something?

Diagrammatically, what happens in the Heap and Stack (in my opinion): LinkedList object on HEAP, referenced by pointers (variables) on STACK

So, why this incompatible behavior that I am seeing? I will be grateful, if you can tell me what is happening in the HEAP and STACK, exactly.

CodePudding user response:

When you do var l1 = list1 in MergeTwoLists it makes both variable store on stack reference to the same heap location, but when you do list1=list1.next the reference stored in list1 changes, but the one in l1 doesn't (cause you have not reassigned it). If you have done something like list1.next = null then you will be able to see the change "propagated" to l1 also since ListNode is a reference type.

  • Related