Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/393.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Stackoverflow与快速排序Java实现_Java_Algorithm_Sorting_Stack Overflow_Quicksort - Fatal编程技术网

Stackoverflow与快速排序Java实现

Stackoverflow与快速排序Java实现,java,algorithm,sorting,stack-overflow,quicksort,Java,Algorithm,Sorting,Stack Overflow,Quicksort,在java中实现快速排序时遇到一些问题。当我运行这个程序时,我得到了一个stackoverflow错误,我不知道为什么。如果有人能指出错误,那就太好了 si是起始指数。ei是期末指数 public static void qsort(int[] a, int si, int ei){ //base case if(ei<=si || si>=ei){} else{ int pivot = a[si]; int leng

在java中实现快速排序时遇到一些问题。当我运行这个程序时,我得到了一个stackoverflow错误,我不知道为什么。如果有人能指出错误,那就太好了

si是起始指数。ei是期末指数

public static void qsort(int[] a, int si, int ei){

    //base case
    if(ei<=si || si>=ei){}


    else{ 
        int pivot = a[si]; 
        int length = ei - si + 1; 
        int i = si+1; int tmp; 

        //partition array 
        for(int j = si+1; j<length; j++){
            if(pivot > a[j]){
                tmp = a[j]; 
                a[j] = a[i]; 
                a[i] = tmp; 

                i++; 
            }
        }

        //put pivot in right position
        a[si] = a[i-1]; 
        a[i-1] = pivot; 

        //call qsort on right and left sides of pivot
        qsort(a, 0, i-2); 
        qsort(a, i, a.length-1); 
    }
}
publicstaticvoidqsort(int[]a,int-si,int-ei){
//基本情况
如果(ei=ei){}
否则{
int pivot=a[si];
整数长度=ei-si+1;
int i=si+1;int tmp;
//分区阵列
对于(int j=si+1;j a[j]){
tmp=a[j];
a[j]=a[i];
a[i]=tmp;
i++;
}
}
//把枢轴放在正确的位置
a[si]=a[i-1];
a[i-1]=支点;
//在轴的左右两侧调用qsort
qsort(a,0,i-2);
qsort(a,i,a.length-1);
}
}

您可能有一个无限递归错误。从我的快速扫描中不确定,但是

即使您不这样做,您仍然将在这个实现中使用大量堆栈。足以导致堆栈溢出。如果用100万个已经排序的项目来调用它,会发生什么?您将它们划分为1和999999项,然后递归。所以你需要一百万个堆栈帧来完成这项工作

有很多方法可以解决这个问题,包括在两个范围中较小的范围上递归和在两个范围中较大的范围上迭代,或者自己在堆数据结构中实现堆栈,等等。不过,您可能希望做得更好,因为深堆栈也意味着您正在突破O(n lg n)排序界限

p、 错误在这里:

qsort(a, 0, i-2); 
qsort(a, i, a.length-1); 
应该是

qsort(a, si, i-2);
qsort(a, i, ei);

首先,您应该按照Keith的建议修复qsort递归调用的边界,否则您总是一次又一次地对整个数组进行排序。您必须调整分区循环:j是一个索引,从子数组的开始到它的结束(包括最后一个元素)。所以必须从si+1循环到ei(包括ei)

这是正确的代码。我运行了一些测试用例,它看起来很好

    public static void qsort(int[] a, int si, int ei){
    //base case
    if(ei<=si || si>=ei){}

    else{ 
        int pivot = a[si]; 
        int i = si+1; int tmp; 

        //partition array 
        for(int j = si+1; j<= ei; j++){
            if(pivot > a[j]){
                tmp = a[j]; 
                a[j] = a[i]; 
                a[i] = tmp; 

                i++; 
            }
        }

        //put pivot in right position
        a[si] = a[i-1]; 
        a[i-1] = pivot; 

        //call qsort on right and left sides of pivot
        qsort(a, si, i-2); 
        qsort(a, i, ei); 
    }
}
publicstaticvoidqsort(int[]a,int-si,int-ei){
//基本情况
如果(ei=ei){}
否则{
int pivot=a[si];
int i=si+1;int tmp;
//分区阵列
对于(int j=si+1;j a[j]){
tmp=a[j];
a[j]=a[i];
a[i]=tmp;
i++;
}
}
//把枢轴放在正确的位置
a[si]=a[i-1];
a[i-1]=支点;
//在轴的左右两侧调用qsort
qsort(a,si,i-2);
qsort(a,i,ei);
}
}
您可以尝试以下方法:

public void sort(int[] A) {
        if (A == null || A.length == 0)
            return;
        quicksort(A, 0, A.length - 1);
    }

    public void quicksort(int[] A, int left, int right) {
        int pivot = A[left + (right - left) / 2];
        int i = left;
        int j = right;
        while (i <= j) {
            while (A[i] < pivot) {
                i++;
            }
            while (A[j] > pivot) {
                j--;
            }
            if (i <= j) {
                exchange(i, j);
                i++;
                j--;
            }
        }

        if(left < j)
            quicksort(A,left,j);
        if(i < right)
            quicksort(A,i,right);
    }

    public void exchange(int i, int j){
        int temp=A[i];
        A[i]=A[j];
        A[j]=temp;
    }

    public String toString() {
        String s = "";
        s += "[" + A[0];
        for (int i = 1; i < A.length; i++) {
            s += ", " + A[i];
        }
        s += "]";
        return s;
    }
public void排序(int[]A){
如果(A==null | | A.length==0)
返回;
快速排序(A,0,A.长度-1);
}
公共无效快速排序(int[]A,int左,int右){
int pivot=A[left+(right-left)/2];
int i=左;
int j=右;
而(我){
j--;
}
if(i
import java.util.array;
公共类快速排序{
公共静态整数透视(整数[]a,整数低,整数高){
int mid=(低+高)/2;
int pivot=a[lo]+a[hi]+a[mid]-Math.min(Math.min(a[lo],a[hi]),a[mid])-Math.max(Math.max(a[lo],a[hi]),a[mid]);
如果(枢轴==a[lo])
返回lo;
else if(pivot==a[hi])
返回hi;
中途返回;
}
公共静态int分区(int[]a,int-lo,int-hi){
int k=枢轴(a、lo、hi);
//系统输出println(k);
互换(a、lo、k);
//系统输出打印项次(a);
int j=hi+1;
int i=lo;
while(true){
while(a[lo]=j)断裂;
互换(a、i、j);
}
互换(a、lo、j);
返回j;
}
公共静态无效排序(int[]a、int-lo、int-hi){

if(hi//刚刚为这个实现了tester类,它会工作的

公共int[]排序(int[]A,int-from,int-to){

if(from1)
排序(A、from、pivot-1);

如果(pivot+1Quicksort对顺序正确的输入稍微敏感,那么它可以跳过一些交换。Mergesort没有任何此类优化,这也使得Quicksort比Mergesort快一点

int分区(int数组[],int太大索引,int太小索引)
{
int x=数组[索引太大];
int i=太大的索引;
int j=太小的索引;
内部温度;
做
{                 
while(x数组[i])
{
i++;
} 
if(i对于(inti=0;i来说,这应该是非常恰当的

public void快速排序(长[]a){
int startingIndex=0;
int-endingIndex=a.length-1;
qsort(a,起始索引,终止索引);
}
私有void qsort(long[]a,int-startingIndex,int-endingIndex){
if(开始索引<结束索引){
int middleIndex=分区(a,开始索引,结束索引);
qsort(a,起始指数,中间指数-1);
qsort(a,
import java.util.Arrays;


public class QuickSort {


    public static int pivot(int[] a, int lo, int hi){
        int mid = (lo+hi)/2;
        int pivot = a[lo] + a[hi] + a[mid] - Math.min(Math.min(a[lo], a[hi]), a[mid]) - Math.max(Math.max(a[lo], a[hi]), a[mid]);

        if(pivot == a[lo])
            return lo;
        else if(pivot == a[hi])
            return hi;
        return mid;
    }

    public static int partition(int[] a, int lo, int hi){

        int k = pivot(a, lo, hi);
        //System.out.println(k);
        swap(a, lo, k);
        //System.out.println(a);
        int j = hi + 1;
        int i = lo;
        while(true){

            while(a[lo] < a[--j])
                if(j==lo)   break;

            while(a[++i] < a[lo])
                if(i==hi) break;

            if(i >= j)  break;
            swap(a, i, j);
        }
        swap(a, lo, j);
        return j;
    }

    public static void sort(int[] a, int lo, int hi){
        if(hi<=lo)  return;
        int p = partition(a, lo, hi);
        sort(a, lo, p-1);
        sort(a, p+1, hi);
    }

    public static void swap(int[] a, int b, int c){
        int swap = a[b];
        a[b] = a[c];
        a[c] = swap;
    }

    public static void sort(int[] a){
        sort(a, 0, a.length - 1);
        System.out.print(Arrays.toString(a));
    }

    public static void main(String[] args) {
        int[] arr = {5,8,6,4,2,9,7,5,9,4,7,6,2,8,7,5,6};
        sort(arr);
    }
}
if(from<to){
    int pivot=partition(A,from,to);
    if(pivot>1)
        sort(A,from, pivot-1);

    if(pivot+1<to)
        sort(A, pivot+1, to);


}

return array;
while(from < to){
    int pivot=A[from];

    while(A[from]<pivot)
        from++;

    while(A[to]>pivot)
        to--;


    if(from<to)   
        swap(A,to,from);



}
    return to;
}

private void swap(int A[], int i, int j){
    int temp = A[i];
    A[i] = A[j];
    A[j] = temp;}
int partition(int array[], int too_big_index, int too_small_index)
{
     int x = array[too_big_index];
     int i = too_big_index;
     int j = too_small_index;
     int temp;
     do
     {                 
         while (x <array[j])
        {
              j --;
        } 
         while (x >array[i])
         {
              i++;
         } 
          if (i < j)
         { 
                 temp = array[i];    
                 array[i] = array[j];
                 array[j] = temp;
         }
     }while (i < j);     
     return j;           // middle  
}

void QuickSort(int num[], int too_big_index, int too_small_index)
{
      // too_big_index =  beginning of array
      // too_small_index = end of array

     int middle;
     if (too_big_index < too_small_index)
    {
          middle = partition(num, too_big_index, too_small_index);
          QuickSort(num, too_big_index, middle);   // sort first section
          QuickSort(num, middle+1, too_small_index);    // sort second section
     }
     return;
}



void main()
{
    int arr[]={8,7,13,2,5,19,1,40,12,34};

    QuickSort(arr,0,9);
    for(int i=0;i<10;i++)
         System.out.println(arr[i]);
}
public void quickSort(long[] a){

  int startingIndex = 0;
  int endingIndex = a.length - 1;
  qsort(a, startingIndex, endingIndex);

}

private void qsort(long[] a, int startingIndex, int endingIndex){

  if (startingIndex < endingIndex){
    int middleIndex = partition(a, startingIndex, endingIndex);
    qsort(a, startingIndex, middleIndex-1);
    qsort(a, middleIndex+1, endingIndex);
  }

}

private int partition(long[] a, int startingIndex, int endingIndex){
  long pivot = a[endingIndex];
  int endWall = endingIndex;
  int wall = 0;

  while (wall < endWall){

    if (a[wall] < pivot){
      wall++;
    }
    else {
      a[endWall] = a[wall];
      a[wall] = a[endWall - 1];
      a[endWall - 1] = pivot;
      endWall--;
    }
  }
  return wall;
}
public class MyQuickSort {

    private int array[];
    private int length;

    public void sort(int[] inputArr) {

        if (inputArr == null || inputArr.length == 0) {
            return;
        }
        this.array = inputArr;
        length = inputArr.length;
        quickSort(0, length - 1);
    }

    private void quickSort(int lowerIndex, int higherIndex) {

        int i = lowerIndex;
        int j = higherIndex;
        // calculate pivot number, I am taking pivot as middle index number
        int pivot = array[lowerIndex+(higherIndex-lowerIndex)/2];
        // Divide into two arrays
        while (i <= j) {
            /**
             * In each iteration, we will identify a number from left side which 
             * is greater then the pivot value, and also we will identify a number 
             * from right side which is less then the pivot value. Once the search 
             * is done, then we exchange both numbers.
             */
            while (array[i] < pivot) {
                i++;
            }
            while (array[j] > pivot) {
                j--;
            }
            if (i <= j) {
                exchangeNumbers(i, j);
                //move index to next position on both sides
                i++;
                j--;
            }
        }
        // call quickSort() method recursively
        if (lowerIndex < j)
            quickSort(lowerIndex, j);
        if (i < higherIndex)
            quickSort(i, higherIndex);
    }

    private void exchangeNumbers(int i, int j) {
        int temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }

    public static void main(String a[]){

        MyQuickSort sorter = new MyQuickSort();
        int[] input = {24,2,45,20,56,75,2,56,99,53,12};
        sorter.sort(input);
        for(int i:input){
            System.out.print(i);
            System.out.print(" ");
        }
    }
}
// the partition function
public static int Sort(int arr[], int start, int end)
{
    int pivot = arr[end];
    int pIndex = start;
    for(int i = start; i< end;i++)
    {
        if(arr[i] <= pivot)
        {
            int temp = arr[i];
            arr[i] = arr[pIndex];
            arr[pIndex] = temp;
            pIndex++;
        }
    }
    int temp = arr[pIndex];
    arr[pIndex] = pivot;
    arr[end] = temp;
    return pIndex;
}
public static void quickSort(int arr[],int start,int end)
{
    if(start>=end)
        return;
    // finding the pivot element
    int pivot = Sort(arr,start,end);
    quickSort(arr,start,pivot-1);
    quickSort(arr,pivot+1,end);
    
}