【问题标题】:Hybrid QuickSort + Insertion sort java.lang.StackOverflowError混合快速排序 + 插入排序 java.lang.StackOverflowError
【发布时间】:2019-06-30 11:18:05
【问题描述】:

我正在尝试计算混合快速排序 - 插入排序的运行时间。但是,当出现更大的数组(约 500k 个元素)时,我得到一个 java.lang.*Error。我能以某种方式克服这一点吗?不使用递归不是一种选择。

代码如下:

public class QuickSort2 {

private static void swap(int[] arr, int x, int y){
       int temp = arr[x];
       arr[x] = arr[y];
       arr[y] = temp;
    }

private static int partition(int[] arr, int lo, int hi){
    int pivot = arr[hi];
    int index = lo - 1;
    for(int i = lo; i < hi; i++){
        if(arr[i] < pivot){
            index++;
            swap(arr, index, i);
        }
    }
    swap(arr, index + 1, hi);
    return index + 1;
} 

public static void quickSort(int[] arr, int lo, int hi){
    if(lo < hi && hi-lo > 10){
        int q = partition(arr, lo, hi);
        quickSort(arr,lo,q-1);
        quickSort(arr,q+1,hi);
        }else{
            InsertionSort.insertSort(arr);
        }    
    }
}

还有插入排序:

public class InsertionSort {

static void insertSort(int[] arr){
    int n = arr.length;
    for (int j = 1; j < n; j++){
        int key = arr[j];
        int i = j-1;
        while ((i >= 0) && (arr[i] > key)){
            arr[i+1] = arr[i];
            i--;
        }
        arr[i+1] = key;
    }         
}

发生错误的行:

quickSort(arr,lo,q-1);
quickSort(arr,q+1,hi);

还有调用代码:

public class RunningTime {

public static void main(String[] args) {
    int[] arr = ReadTest.readToArray("int500k");
    int lo = 0;
    int hi = arr.length - 1;

    long startTime = System.currentTimeMillis();
    QuickSort2.quickSort(arr, lo, hi);
    long stopTime = System.currentTimeMillis();
    long elapsedTime = stopTime - startTime;
    System.out.println("Running time: " + elapsedTime);
    System.out.println("Array is sorted: " + isSorted(arr));
}

}

【问题讨论】:

    标签: java algorithm stack-overflow quicksort insertion-sort


    【解决方案1】:

    您应该将插入排序限制为仅对数组的子集起作用。

    除此之外,我没有发现您的代码有任何其他问题。

    文件int500k 是否已排序?如果是这样,这是快速排序的最坏情况,这意味着递归将有 500k 层深。

    要修复它,您可以例如随机选择枢轴而不是arr[hi]

    【讨论】:

    • @TobiasBrösamle 是的,这就是我的想法。奇怪......快速排序是否在没有插入排序的情况下工作?如果 insertSort 是一个空方法,它是否有效(不会因异常而失败)?
    • 如果 insertSort 是一个空方法,仍然是 *Error。所以我不认为 insertSort 是这里的问题。
    • @TobiasBrösamle 如果 insertSort 是一个空方法并且您删除了&amp;&amp; hi-lo &gt; 10,则执行快速排序?
    • 它最多适用于 14444 个元素。再高就不会了。我承认,这有点奇怪......
    • @meriam 这是因为第一次调用 insertSort 时它对整个数组进行了排序,从而导致快速排序的最坏情况