通用QuickSort导致StackOverflowError

时间:2017-04-15 19:11:35

标签: java generics quicksort

这是我正在编写的Java书中的一个练习题。基本上,目标是使用compareTo按递增顺序对泛型类型元素的数组进行排序。

我正在尝试使用QuickSort来完成它。这是我的代码:

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);
}

问题是,当我使用以下数组测试时:

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

我在以下行获得了StackOverflowError:

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

然后在这一行重复一些:

sort(arr, i, right);

上面一行的重复错误告诉我它可能与无限递归发生有关,但我不知道为什么会这样。

我也不知道为什么它会在while循环线上抛出错误......看起来我在比较arr [i]和pivot时使用的逻辑是否合适?

1 个答案:

答案 0 :(得分:2)

选择枢轴中间元素的行应为:

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

当前代码实际上使用T pivot = arr[right / 2],其中索引right / 2可能小于左,导致从左到右的范围内不存在的数据透视值。

考虑使用小于左到右范围内所有元素值的枢轴值的情况。这可能导致第一个循环提前i超过right或甚至超过数组的末尾,这可能导致堆栈溢出或分段错误。