1

I'm trying to understand how the below implementation of QuickSort works in Java. I've got most of it, but I'm pretty confused how it does anything at all. When you pass in a variable to a function and modify it, it normally doesn't modify the original variable that was passed in. So why does this implementation of quicksort with no return type modify the array passed in?

public static void quickSort(int[] arr, int low, int high) {
    if (arr == null || arr.length == 0)
        return;

    if (low >= high)
        return;

    int middle = low + (high - low) / 2;
    int pivot = arr[middle];

    // make left < pivot and right > pivot
    int i = low, j = high;
    while (i <= j) {
        while (arr[i] <pivot) {
            i++;
        }

        while (arr[j] > pivot) {
            j--;
        }

        if (i <= j) {
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
            i++;
            j--;
        }
    }

    if (low < j)
        quickSort(arr, low, j);

    if (high > i)
        quickSort(arr, i, high);
}
Nat
  • 890
  • 3
  • 11
  • 23
  • 2
    Possible duplicate of [Changing array in method changes array outside](http://stackoverflow.com/questions/21653048/changing-array-in-method-changes-array-outside) – resueman Jan 20 '16 at 15:31

3 Answers3

4

because arrays are treated as Object´s, and in this case they pass the value of the reference to the method, which causes this implementation to work on the array that was passed to this method.

It´s the same as if you would do

public void test(ObjectA obj) {
    obj.setVal(1);
}

In this case you would work on the passed ObjectA and would also invoke the method setVal on this instance. In this case the method invoking inside the method test would also reflect in changes inside the passed instance of this specific objects (because it´s the same instance).

The same happens for arrays

public static void main(String args[]) {
   int[] arr = {1,2,3};
   test(arr);
   System.out.println(arr[0]); // This would print 13 now.
}

public static void test(int[] arr) {
   arr[0] = 13;
}

For further reference you could go through this question

Community
  • 1
  • 1
SomeJavaGuy
  • 7,307
  • 2
  • 21
  • 33
  • Hm interesting, I didn't know Java passed reference and value. I'll read that thread, thanks! – Nat Jan 20 '16 at 15:36
  • 1
    @Nathan it doesn´t pass references directly, just the value of the reference. This might be confusing to think about. But you can notice it when you reassign a paramter, like `arr` in this case. The change of the value of the reference would only be notifiable in the method, and not from the caller (which would work if java would be pass-by-reference). – SomeJavaGuy Jan 20 '16 at 15:38
  • Oh, I think I get it. I'll play around with it more :) – Nat Jan 20 '16 at 15:40
2

Your int[] arr is a reference to an array. This reference is a copy of the reference passed to it, and that reference cannot be changed. However, the array it references, is not copied and when you modify it, these changes are visible to the caller.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
1

Everything in Java is passed by value. If we are talking about non-primitives - Object variables as well as arrays, the VALUE of the variable is a LINK to the object. We can't re-assign the link, but we can change internals of the object.

The thing is that when we pass primitives - they are kept in Stack of the function and their change won't affect value of the variable in method call. But objects are in Heap and they are shared. So we can change it's internals from any place of the call stack.

Azee
  • 1,809
  • 17
  • 23