簡體   English   中英

Java Quicksort算法Stack Overflow與大數組大小

[英]Java Quicksort algorithm Stack Overflow with Big array sizes

我正在努力實現一個Quicksort算法,我必須在數組大小高達100,000的情況下正常工作。 一旦我嘗試排序大小為1,000,000,我就會出現堆棧溢出錯誤(由於我的算法的遞歸功能,這是我最好的理解)。 我知道之前已經在這里提出過這個問題,但這些答案都沒有幫助我。 我已經仔細查看了我的代碼,甚至將它從Java教科書中建模,只是為了仔細檢查,仍然沒有修復。 我一直在這里閱讀至少一個小時試圖解決這個問題,我讀到調用堆棧最多可以容納8MB左右,具體取決於系統。 我想知道是否:

  • 我的算法錯了
  • 1,000,000個元素太大而無法用於快速排序(使用此編譯器)。

編輯:對任何感興趣的人:我發現將我的隨機間隔從1-9增加到1-n(n是正在排序的序列的大小,例如:1-1000000),我的快速排序速度非常快,當然也沒有有任何溢出問題。

我現在要和司機一起提交我的代碼,希望有人可以快速告訴我出錯的地方。

public class QuickSort {

public static void main(String[] args) {

    //JUST TO TEST THAT IT WORKS
    int[]A = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1}; //worst case

    quickSort(A, 0, A.length-1);

    //print the array
    for (int a :A)
        System.out.print(a+" ");
    System.out.println();

}

/**
 * Quicksort algorithm, O(n log n) best and average case, O(n^2) worst case
 * @param S sequence to sort
 * @param a the lower bound of sequence
 * @param b upper bound of sequence
 */
public static void quickSort(int[]S, int a, int b) {
    if (a >= b)
        return;
    int p = S[b]; //setting pivot to the last element in sequence
    int l = a;
    int r = b - 1;
    int temp;

    while (l <= r) { //once left and right have crossed this will end while
        while (l<= r && S[l] <= p) {
            l++; //move in from left side until found an element greater than the pivot
        }
        while (l <= r && S[r] >= p) {
            r--; //move in from right side until element found less than the pivot
        }
        if (l <= r) {
            //swap S[l] and S[r] //swap the left and right elements if they haven't crossed
            temp = S[l];
            S[l] = S[r];
            S[r] = temp;
            l++;
            r--;
        }
    }
    //left and right have crossed here
    //swap S[l] and S[b] //put the pivot back to the new partition spot
    temp = S[l];
    S[l] = S[b];
    S[b] = temp;
    quickSort(S, a, l-1); //call quicksort on our new sublists partitioned around our pivot
    quickSort(S, l+1, b);
    //recursive calls

}

}

司機:

import java.util.Random;

public class SortingCompare {

public static void main(String[] args) {
    Random rand = new Random();
    System.out.printf("Sorting Run Times:\n");
    System.out.printf("Array Size   Insertion Sort%5s%s\n", " ","Quick sort");

        int A[] = new int[100000];
        int n = 100000;

        for (int i = 0; i < n; i++) {
            A[i] = rand.nextInt(9) + 1; //1-9
        }
        //array is filled with random integers

        //long start = System.currentTimeMillis();
        //InsertionSortInPlace.insertionSort(A);
        //long insertionTime = System.currentTimeMillis() - start;

        //for (int i = 0; i < n; i++) {
        //    A[i] = rand.nextInt(9) + 1; //1-9
        //}

        long startQuickSort = System.currentTimeMillis();
        QuickSort.quickSort(A, 0, A.length - 1);
        long quickTime = System.currentTimeMillis() - startQuickSort;

        System.out.printf("%-5d%10dms%15s%dms\n", n, insertionTime, " ", quickTime);

}

}

您應該首先對兩個分區中較小的一個進行排序,以最小化堆棧使用,並對小於16個元素的分區使用插入排序。

您還需要查找Quicksort算法。 在每個內循環中不需要兩個測試:它們完全破壞了算法的要點; 並且您的實施細節與Sedgewick的規范版本不同。

您可以使用Java中的快速排序,該快速排序針對性能和內存使用進行了優化,因此在您的代碼中替換:

quickSort(A, 0, A.length - 1);

有:

Arrays.sort(A);

要運行修改后的代碼,您需要進行以下導入:

import java.util.Arrays;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM