-1

I am trying to write a program for quicksort using singly linked list in java.

Below is the code.

public class QuickSortInSLinkedList {
Node head;
private static class Node{
    private int data;
    private Node next;

    Node(int data){
        this.data = data;
        this.next = null;
    }
}


public void printList(Node head){
    Node node = head;
    while(node != null){
        System.out.print(node.data+" ,");
        node = node.next;
    }
}

private Node getLastNode(Node head){
    Node node = head;
    while(node != null && node.next != null){
        node = node.next;
    }
    return node;
}

public void push(int data){
    Node node = new Node(data);

    if(head == null){
        head = node;
        return;
    }

    node.next = head;
    head = node;
}

void quickSort(Node head){
    Node lastnode = getLastNode(head);
    head = _quickSort(head, lastnode);
    return;
}

Node _quickSort(Node low, Node high){
    Node newHead = null, newTail = null;

    if(low == null || low == high){
        return low;
    }

    Node part = partition(low, high, newHead, newTail);

    if (newHead != part){
        Node temp = newHead;
        while(temp.next != part){
            temp = temp.next;
        }

        temp.next = null;

        newHead = _quickSort(newHead, temp);
        temp = getLastNode(newHead);
        temp.next = part;

    }

    part.next = _quickSort(part.next, newTail);
    return newHead;
}

private Node partition(Node low, Node high, Node newHead, Node newTail){
    Node pivot = high;
    Node previous = null, current = head, tail = pivot;

    while(current != pivot){
        if (current.data < pivot.data){
            if (newHead == null)
                newHead = current;

            previous = current;
            current = current.next;
        }else{
            if(previous != null)
                previous.next = current.next;

            Node temp = current.next;
            current.next = null;
            tail.next = current;
            tail = current;
            current = temp;
        }
    }

    if(newHead == null){
        newHead = pivot;
    }

    newTail = tail;

    return pivot;
}

public static void main(String[] args){
    QuickSortInSLinkedList list = new QuickSortInSLinkedList();
    list.push(5);
    list.push(35);
    list.push(7);
    list.push(8);
    list.push(34);
    list.push(23);

    System.out.println("Linked list before sorting");
    list.printList(list.head);

    System.out.println("\n Linked list after sorting");
    list.quickSort(list.head);
    list.printList(list.head);

}

}

I understand that since in java we have pass by reference value, this code should work but in line 62 i.e. variables newHead and newTail is always received as null after the call to partition method.

below is the error

Exception in thread "main" java.lang.NullPointerException 23 ,34 ,8 ,7 ,35 ,5 , at implementation.sorting.QuickSortInSLinkedList$Node.access$100(QuickSortInSLinkedList.java:6) Linked list after sorting at implementation.sorting.QuickSortInSLinkedList._quickSort(QuickSortInSLinkedList.java:62) at implementation.sorting.QuickSortInSLinkedList.quickSort(QuickSortInSLinkedList.java:47) at implementation.sorting.QuickSortInSLinkedList.main(QuickSortInSLinkedList.java:123)

Please help me understand why is it so. Thanks

Astlez
  • 35
  • 5
  • Java is strictly [pass-by-value, not pass-by-reference](http://stackoverflow.com/q/40480/4125191). – RealSkeptic Jul 15 '17 at 13:40
  • I went through this link https://stackoverflow.com/questions/5298421/why-doesnt-java-support-pass-by-reference-like-c , it mentions - "it passes object references by value. Because two copies of the same reference refer to the same actual object, changes made through one reference variable are visible through the other." , I am confused that way newHead should also get modified ? – Astlez Jul 15 '17 at 13:46
  • Yes, you are confused. If an argument is an object, the object is not duplicated and any changes to the **fields of the object** will be seen outside of the method. But the argument *itself* cannot be changed - you can't assign to the argument (you can, but it will not be seen outside of the method), you can only modify fields in the object it refers to. – RealSkeptic Jul 15 '17 at 13:48
  • Thanks @RealSkeptic – Astlez Jul 15 '17 at 13:56

1 Answers1

0

Java does manipulate objects by reference, and all object variables are references. However, Java doesn't pass method arguments by reference; it passes them by value.

Chirag Goti
  • 116
  • 1