[英]Stackoverflowerror in Quicksort implementation
import java.util.Random;
public class Quicksort {
private int partition(int arr[], int first, int last) {
int pivot = arr[last]; //Using last element as pivot
int i = (first-1);//index of smaller element
for (int j = first; j < last; j++) {
//if current element is smaller than or equal to pivot
//then swap the elements
if (arr[j] <= pivot) {
i++;
//swapping occurs here
//make a temp variable to the first element
//swap arr[j] and arr[i]
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
//i++;
}
}
int temp = arr[i+1];
arr[i+1] = arr[last];
arr[last] = temp;
return i+1;
}
private void quickSort(int arr[], int first, int last) {
if (first < last) {
int pivindex = partition(arr, first, last);
quickSort(arr, first, pivindex-1);
quickSort(arr, pivindex+1, last);
}
}
public void sort(int[] arr) {
quickSort(arr, 0, arr.length - 1);
}
public static int[] getRandoms(int count) {
return new Random().ints().limit(count).toArray();
}
public static void main(String[] args) {
Quicksort fix = new Quicksort();
int[] randoms = getRandoms(40000);
double startTime = System.currentTimeMillis();
fix.sort(randoms);
double endTime = System.currentTimeMillis();
System.out.println("Performance Time on Random Data:" + (endTime - startTime));
//Benchmarking quicksort on already sorted data
startTime = System.currentTimeMillis();
fix.sort(randoms);
endTime = System.currentTimeMillis();
System.out.println("Performance Time on Sorted Data:" + (endTime - startTime));
}
}
我不完全確定為什么會收到StackoverflowError。 當我只排序一次時,代碼運行良好,但是,如果我嘗試對同一數據進行兩次排序,那就是出現錯誤。
我了解發生Stackoverflowerror是因為使用遞歸存在問題。 在這種情況下,我的錯誤來自
quicksort.Quicksort.quickSort(Quicksort.java:36)處的線程“ main”中的異常java.lang.StackOverflowError
是..
if (first < last) {
int pivindex = partition(arr, first, last);
quickSort(arr, first, pivindex-1);
quickSort(arr, pivindex+1, last);
}
@ mackycheese21當我說它運行良好時,我的意思是,如果我使用可以打印並看到的較小數組,它將按排序將其打印出來。 排序40,000個隨機整數也是如此,直到我嘗試對已經排序的數組進行排序。
所以我想您只是想檢查數組是否已排序。 因為這看起來效率不高,所以我能想到的唯一另一件事是,您的partition
方法是對有序數組給出第一個或最后一個索引-進行分區時給出一個空數組和整個數組。 這可能導致無限遞歸。
我建議您只添加一個檢入partition
以檢查索引是指向第一個還是最后一個索引,然后如果確實發生了,就在中間拆分。
QuickSort的平均復雜度為O (n log(n))。 但是,最壞的情況是O (n ^ 2)。 這也與遞歸調用的“深度”有關。
平均情況下,深度為log(n),對於40,000個數字而言,深度約為15。因此,當每次遞歸調用自身時,每次將當前數組分割成兩半時,深度都會達到15。
最壞的情況:將樞軸作為當前片段的最后一個元素。 第二次運行quicksort時,數字已經排序。 因此,無論如何樞軸最終都將結束,並且您的陣列被分成2個部分。 一個是數組元素1到39999,另一個是元素40000。恭喜,您已經成功找到Quicksorts最壞的情況。 所有通話的“左側”深度為40,000。
因此,當一個方法調用另一個方法時,信息被壓入堆棧。 在第一輪中,很少有人被推入堆棧。 在第二種情況下,將40,000個方法調用壓入堆棧,從而導致溢出。
private int partition(int arr[], int first, int last) {
int pivot = arr[last]; //Using last element as pivot
int i = (first-1);//index of smaller element
for (int j = first; j < last; j++) {
//if current element is smaller than or equal to pivot
//then swap the elements
if (arr[j] <= pivot) {
i++;
//swapping occurs here
//make a temp variable to the first element
//swap arr[j] and arr[i]
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
//i++;
}
}
int temp = arr[i+1];
arr[i+1] = arr[last];
arr[last] = temp;
return i+1;
}
我發現問題出在分區方法的for循環中。 謝謝,所有回答並嘗試幫助我的人。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.