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