Java快速排序-堆栈溢出

Java快速排序-堆栈溢出,java,stack-overflow,infinite-loop,quicksort,Java,Stack Overflow,Infinite Loop,Quicksort,我正在尝试实现一个版本的quick sort,它使用一个计算如下的pivot: pivot=(a[start]+a[end]+a[size/2])/3 ATM它可以在大小为6或更小的数组上完美地工作,但是一旦对大小为7或更大的数组进行排序,程序就会进入无限循环。到目前为止,我对递归的理解还不牢固,所以我怀疑它正在崩溃。我知道它在检查索引4和6时会进入一个循环,然后只持续检查这些索引 编辑:添加了对quickSort()的调用,并修复了一些格式问题 public static void quick

我正在尝试实现一个版本的quick sort,它使用一个计算如下的pivot:

pivot=(a[start]+a[end]+a[size/2])/3

ATM它可以在大小为6或更小的数组上完美地工作,但是一旦对大小为7或更大的数组进行排序,程序就会进入无限循环。到目前为止,我对递归的理解还不牢固,所以我怀疑它正在崩溃。我知道它在检查索引4和6时会进入一个循环,然后只持续检查这些索引

编辑:添加了对quickSort()的调用,并修复了一些格式问题

public static void quickSort(double[] list, int start, int end){
    if (end - start > 1){
      int pivot = split(list, start, end);
      quickSort(list, start, pivot - 1);
      quickSort(list, pivot + 1, end);
    } 
    if ( (end - start) == 1){
      if (list[start] > list[end]){
        double temp = list[start];
        list[start] = list[end];
        list[end] = temp;
      }
    }
  }

  public static int split(double[] list, int start, int end){
    // splitPoint = (a[begin] + a[end] + a[size/2]) / 3
    int size = end - start + 1;
    double pivotValue = (list[start] + list[end] + list[size/2]) / 3;

    int leftPosition = start;
    int rightPosition = end;
    double temp = 0;

    while (true){
      // find a value to swap on the left side of pivot
      while ( (leftPosition <= rightPosition) && (list[leftPosition] <= pivotValue) ){
        leftPosition++;
      }

      // find a value to swap on the right side of pivot
      while ( (rightPosition >= leftPosition) && (list[rightPosition] >= pivotValue) ){
        rightPosition--;
      }
      // if positions pass each other
      if (rightPosition < leftPosition){
        break;
      } else {
        // swap values
        temp = list[leftPosition];
        list[leftPosition] = list[rightPosition];
        list[rightPosition] = temp;
      }
    }
    return rightPosition;
  }

  public static void main(String[] args){
      double[] list = {7, 6, 5, 4, 3, 2, 1};
      quickSort(list, 0, list.length-1);
  }
publicstaticvoidquicksort(双[]列表,int开始,int结束){
如果(结束-开始>1){
int pivot=拆分(列表、开始、结束);
快速排序(列表、开始、透视-1);
快速排序(列表,透视+1,结束);
} 
如果((结束-开始)==1){
如果(列表[开始]>列表[结束]){
双温=列表[开始];
列表[开始]=列表[结束];
列表[结束]=温度;
}
}
}
公共静态整型拆分(双[]列表,整型开始,整型结束){
//拆分点=(a[开始]+a[结束]+a[大小/2])/3
int size=end-start+1;
双数据透视值=(列表[开始]+列表[结束]+列表[大小/2])/3;
int leftPosition=开始;
int rightPosition=结束;
双温=0;
while(true){
//在轴的左侧查找要交换的值
while((leftPosition=pivotValue)){
右位--;
}
//如果位置相互传递
如果(右位置<左位置){
打破
}否则{
//交换值
临时=列表[左位置];
列表[左位置]=列表[右位置];
列表[右位置]=温度;
}
}
返回正确位置;
}
公共静态void main(字符串[]args){
双[]列表={7,6,5,4,3,2,1};
快速排序(list,0,list.length-1);
}

算法的第一步是:

从数组中拾取一个称为轴的元素

此表达式不会执行以下操作:

(list[start] + list[end] + list[size / 2]) / 3
它只计算3个数字的平均值,其中一个数字可能位于正在排序的分区之外(请参见start+)。
因此,给定此数组:
{1,2,3,4,5,6,7}
start=4
end=6
拾取的项将是
(5+7+2)/3=4.(6)7
,并且该不是分区
{5,6,7}
的元素
您应该做的是选择
start…end
范围内的一个数字作为轴的索引

开始+ 我相信您实际考虑的轴心(分区的第一个、最后一个和中间元素的平均值)是:

虽然这个表达式不从分区中选取元素,但它将选取一个不大于/小于分区中所有值的值,并且它将工作

使用a/3枢轴的工作解决方案:
void快速排序(双[]列表,整数开始,整数结束){
int size=end-start+1;
//这是“经典”支点
//双数据透视值=列表[开始+(结束-开始)/2];
双数据透视值=(列表[开始]+列表[结束]+列表[开始+(大小/2)])/3.0;
int leftPosition=开始;
int rightPosition=结束;
while(左位置数据透视值){
右位--;
}

if(leftPosition)堆栈溢出情况最好通过在IDE中运行并启用“异常时中断”来解决——这样,您可以检查堆栈并查看算法出错的位置。由于它在相对较小的情况下中断,您可以在
if(end-start>1)处设置断点{
然后等待其中一个值为负值。
(list[start] + list[end] + list[start + (size / 2)]) / 3.0
void quickSort(double[] list, int start, int end) {
    int size = end - start + 1;
    // this is the 'classic' pivot
    // double pivotValue = list[start + (end - start) / 2];
    double pivotValue = (list[start] + list[end] + list[start + (size / 2)]) / 3.0;
    int leftPosition = start;
    int rightPosition = end;

    while (leftPosition <= rightPosition) {
        while (list[leftPosition] < pivotValue) {
            leftPosition++;
        }
        while (list[rightPosition] > pivotValue) {
            rightPosition--;
        }

        if (leftPosition <= rightPosition) {
            exchange(list, leftPosition, rightPosition);
            leftPosition++;
            rightPosition--;
        }
    }
    if (start < rightPosition)
        quickSort(list, start, rightPosition);
    if (leftPosition < end)
        quickSort(list, leftPosition, end);
}

void exchange(double[] list, int i, int j) {
    double temp = list[i];
    list[i] = list[j];
    list[j] = temp;
}