简体   繁体   中英

Generic QuickSort causing StackOverflowError

This is a practice problem in the Java book I'm working through. Basically, the goal is to sort an array of generic-type elements in increasing order using compareTo.

I'm trying to use QuickSort to do it. Here's my code:

public static <T extends Comparable<? super T>>
void sort (T[] arr)
{
    // If arr is null, empty,
    // or only has 1 element,
    // it is already sorted

    if (arr == null || arr.length == 0
            || arr.length == 1)
        return;

    // Call overloaded sort method

    sort(arr, 0, arr.length - 1);
}

// HELPER METHOD FOR SORT METHOD

public static <T extends Comparable<? super T>>
void sort(T[] arr, int left, int right)
{

    // To be used while sorting

    int i = left;
    int j = right;

    // Check if left and
    // right indices are out
    // of order. If they are,
    // nothing can be done

    if (right <= left)
        return;

    // Middle element used
    // as pivot

    T pivot = arr[(left + (right - left)) / 2];

    // temp will be used
    // to swap elements later

    T temp;

    // QuickSort algorithm

    while (i <= j)
    {
        // Look for values on
        // the left greater than
        // the pivot and values
        // on the right smaller
        // than the pivot

        // When you find both, swap them

        while (arr[i].compareTo(pivot) < 0)
        {
            i++;
        }

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

        // Check that i hasn't
        // passed j already

        if (i <= j)
        {

            // Swap the items

            temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;

            // Move both indices
            // to their next position

            i++;
            j--;
        }
    }

    // Recursive calls to the
    // sort method

    if (left < j)
        sort(arr, left, j);
    if (i < right)
        sort(arr, i, right);
}

The trouble is, when I test this using the following array:

String[] wordArray = {"Droplet", "Blueberry", "Elephant",
            "Fate", "Apple", "Coconut", "Darjeeling"};

I get a StackOverflowError at the following line:

while (arr[i].compareTo(pivot) < 0)

And then a bunch of repeating ones at this line:

sort(arr, i, right);

The repeating errors at the line above tells me it might have something to do with infinite recursion happening, but I don't know why it would be.

I also don't know why it's throwing the error at the while loop line... it looks like the logic I used in comparing arr[i] to the pivot is okay?

The line to choose middle element for pivot should be:

    T pivot = arr[left + (right - left) / 2];

the current code is effectively using T pivot = arr[right / 2] , where the index right / 2 could be less than left, resulting in a pivot value that doesn't exist within the range left to right.

Consider the case where a pivot value less than all of the element values in the range left to right is used. This could cause the first loop to advance i past right or even past the end of the array, which could cause stack overflow or segmentation fault.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM