Search code examples
javamergesort

Changing an object in Java inside a function


I tried to implement a merge sort for a list using the added code. The problem I encountered, which I have no idea what is causing it is: If I call recursiveMergeSort directly I get the correct sorted list back, but if I try to sort the list by calling mergeSort on it I only get a list of the first element.

I.E if in main I have a list = "d","a","f","g","b" then

list = recursiveMergeSort(list) // list will be "a","b","d","f","g"
mergeSort(list) // list will be "a"

What do I need to do for mergSort to give the same result as recursiveMergeSort? (The public void function was given to me in the API, that's why I created a private recursive function)

public static void mergeSort(List list) {
if (list == null) throw new NullPointerException("list");
    list = recursiveMergeSort(list);
    /* If I check list here, I get the correct result,
    only in the original it's wrong */
}
/** a recursive function for the merge sort  */
private static List recursiveMergeSort(List list) {

    int length = listLength(list);
    System.out.println(length);
    if (length <= 1) { // base case, list length 1
        return list;
    }

    // create sublists
    List left = new List(), right = new List();
    List.Node indexList = list.head;
    left.head = list.head;
    for (int i = 0; i < length / 2 - 1; i++ ) {
        indexList = indexList.getNext();
    }
    right.head = indexList.getNext();
    indexList.setNext(null);

    left = recursiveMergeSort(left); // recursively work on them
    right = recursiveMergeSort(right);
    List tempList = mergeLists(left, right); // final result
    return tempList;
}

(Merge lists just merges two ordered lists into an ordered list.)


Solution

  • list is a reference variable, referencing a List value.

    You can't change a referenced value just by changing the value of a variable that references it.

    Change your initial function to:

    public static List mergeSort(List list) {
    if (list == null) throw new NullPointerException("list");
        return recursiveMergeSort(list);
    }
    

    The value you return will be the sorted list.

    If you do need to change the argument in place, try:

    public static void mergeSort(List list) {
    if (list == null) throw new NullPointerException("list");
        List temp = recursiveMergeSort(list);
        list.clear();
        list.addAll(temp);
    }
    

    You can change an object by calling methods on it, or changing the values of fields in it, either the object itself or components of it. indexList in your recursiveMergeSort is another reference for nodes in your starting list, and you are altering it with the setNext(null)