简体   繁体   English

QuickSort java.lang.StackOverflowError

[英]QuickSort java.lang.StackOverflowError

I am trying to calculate the execution time of quicksort algorithm in three cases "Mid pivot, first pivot, random pivot" of an array was already sorted. 我正在尝试在数组的“中间枢轴,第一个枢轴,随机枢轴”已经排序的三种情况下计算快速排序算法的执行时间。

The mid pivot and random works fine with any size, but the first pivot case gives stackoverflow if the size was greater than 25000. 中间枢轴和随机数在任何大小下都可以正常工作,但是如果大小大于25000,则第一个枢轴案例会产生stackoverflow。

Heres the code: 这是代码:

static void q_sort( int left, int right)
{

int pivot;
int l_hold, r_hold;

  l_hold = left;
  r_hold = right;
  pivot = array[left];
  while (left < right)
  {
    while ((array[right] >= pivot) && (left < right))
      right--;
    if (left != right)
    {
      array[left] = array[right];
      left++;
    }
    while ((array[left] <= pivot) && (left < right))
      left++;
    if (left != right)
    {
      array[right] = array[left];
      right--;
    }
  }
  array[left] = pivot;
  pivot = left;
  left = l_hold;
  right = r_hold;
  if (left < pivot)
    q_sort(left,(int) pivot-1);
  if (right > pivot)
    q_sort( (int)pivot+1, right);
}

and heres the calling code: 这是调用代码:

double startTime1 = System.currentTimeMillis();
q_sort(0,size -1);
double stopTime1 = System.currentTimeMillis();
double elapsedTime1 = stopTime1 - startTime1;      
System.out.println(elapsedTime1);

You didn't tell how the array was generated, but I suspect it was already sorted. 您没有告诉您数组是如何生成的,但是我怀疑它已经被排序了。

The problem is the following: if you quicksort an already sorted array, the first pivot causes the following recursion: 0..24999, 1..24999, 2..24999, 3..24999, 4..24999 which takes a lot of stack space and results in a stack overflow. 问题如下:如果对已排序的数组进行快速排序,则第一个枢轴将导致以下递归:0..24999、1..24999、2..24999、3..24999、4..24999,这会花费很多堆栈空间并导致堆栈溢出。 This is because the array is 0..24999 and the pivot is 0, and the second partition then will become 1..24999. 这是因为数组是0..24999,数据透视表是0,第二个分区将变成1..24999。

You should eliminate one of the tail calls. 您应该消除尾叫之一。 Which tail call to eliminate depends on which partition is smaller. 消除哪个尾部调用取决于哪个分区较小。 You want the recursion to process as little data as possible. 您希望递归处理尽可能少的数据。 One of the recursions is simply replaced by a loop. 递归之一简单地由循环代替。 This tail recursion elimination has already been explained at Quicksort and tail recursive optimization 尾部递归消除已在Quicksort和尾部递归优化中进行了解释

Anyway, I recommend using an existing quicksort algorithm instead of coding it yourself unless this is a homework question. 无论如何,我建议您使用现有的quicksort算法,而不要自己编码,除非这是一个家庭作业问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM