首页 > 解决方案 > 3 方式快速排序:线程“主”java.lang.StackOverflowError 中的异常

问题描述

在实现 3-way-quicksort 时,我遇到了一条我不知道如何修复的错误消息。这是控制台中错误的回溯:

Exception in thread "main" java.lang.StackOverflowError
    at projects.Main.quickSortByRecursion(Main.java:45)
    at projects.Main.quickSortByRecursion(Main.java:47)
    at projects.Main.quickSortByRecursion(Main.java:47)
    at projects.Main.quickSortByRecursion(Main.java:47)

这适用于更多行,大约 200 行。基本上我只是想实现一个 3-way-quicksort。这是我的代码:

static void partition(int[] intArray, int low, int high, int i, int j)    {

    if(high - low <= 1) {
        if(intArray[high] < intArray[low]) {
            swapElements(intArray, high, low);
        }
    }   else    {
        i = low;
        j = high;
        return;
    }
    int midpoint = low;
    int pivot = intArray[high];
    while (midpoint <= high)    {
        if(intArray[midpoint] < pivot)  {
            swapElements(intArray, low + 1, midpoint + 1);
        }
        else if(intArray[midpoint] == pivot)    {
            midpoint += 1;
        }
        else if(intArray[midpoint] > pivot) {
            swapElements(intArray, midpoint, high - 1);
        }
        i = low - 1;
        j = midpoint;
    }
}

static void quickSort(int intArray[])   {
    quickSortByRecursion(intArray, 0, intArray.length - 1);
}

static void quickSortByRecursion(int intArray[], int low, int high)   {
    if(low >= high)  {
        return;
    }
    int i = 0;
    int j = 0;

    partition(intArray, low, high, i, j);
    quickSortByRecursion(intArray, low, i);
    quickSortByRecursion(intArray, j, high);
}

static void swapElements(int intArray[], int low, int high) {
    int temporaryValue = intArray[low];
    intArray[low] = intArray[high];
    intArray[high] = temporaryValue;
}

public static void main(String[] args) {
    int[] intArray = { 1, 3, 2, 4, 7, 9, 8, 5, 4, 6 };

    for(int i : intArray)   {
        System.out.println(i);
    }
    quickSort(intArray);

    for(int i: intArray)    {
        System.out.println(i);
    }
}

}

我还实现了其他快速排序,一个是递归,第二个是内部插入排序,我还没有遇到这个问题。我一直在寻找类似的答案,但唯一发现的是 int/long 参数的使用不正确。有任何想法吗?

标签: javasortingstack-overflow

解决方案


Java 是按值传递的。因此在调用方法 quickSortByRecursion 中不会看到在分区方法中更改 i 和 j。

以下是修复 StackOverflowError 错误的解决方法。

    static void partition(int[] intArray, int low, int high, int[] arr) {

    if (high - low <= 1) {
        if (intArray[high] < intArray[low]) {
            swapElements(intArray, high, low);
        }
    } else {
        arr[0] = low;
        arr[1] = high;
        return;
    }
    int midpoint = low;
    int pivot = intArray[high];
    while (midpoint <= high) {
        if (intArray[midpoint] < pivot) {
            swapElements(intArray, low + 1, midpoint + 1);
        } else if (intArray[midpoint] == pivot) {
            midpoint += 1;
        } else if (intArray[midpoint] > pivot) {
            swapElements(intArray, midpoint, high - 1);
        }
        arr[0] = low - 1;
        arr[1] = midpoint;
    }
}

static void quickSort(int intArray[]) {
    quickSortByRecursion(intArray, 0, intArray.length - 1);
}

static void quickSortByRecursion(int intArray[], int low, int high) {
    if (low >= high) {
        return;
    }
    int[] arr = {0, 0};

    partition(intArray, low, high, arr);
    quickSortByRecursion(intArray, low, arr[0]);
    quickSortByRecursion(intArray, arr[1], high);
}

static void swapElements(int intArray[], int low, int high) {
    int temporaryValue = intArray[low];
    intArray[low] = intArray[high];
    intArray[high] = temporaryValue;
}

public static void main(String[] args) {
    int[] intArray = { 1, 3, 2, 4, 7, 9, 8, 5, 4, 6 };

    for (int i : intArray) {
        System.out.println(i);
    }
    quickSort(intArray);

    for (int i : intArray) {
        System.out.println(i);
    }
    
}

推荐阅读