就地快速排序java

时间:2014-04-17 10:33:50

标签: java sorting quicksort

我要为java编写一个快速排序方法,在本地交换条目,这意味着没有辅助数组来存储东西,并且交换是就地完成的。所以我使用了一些变量来帮助跟踪“低”“hi”和“pivot”指针的位置。

当我运行测试时,它会给我Stack Overflow错误。但是当我在main()上使用一些简单的测试数组运行它时,例如:

int[] A = { 0, 0, 1, 1, 0};

它给了我正确的结果。

我猜这个bug(大概是一个无限循环)只是由一些特殊情况触发,但我找不到它。

这是我的代码。

  public static void quicksort( int[] A, int low, int hi ){


  int len = hi - low + 1;


  if (len < 2){   // base case 1
         return;
         }

  else if(len == 2){  // base case 2 (bug-prone now)
      if(A[low]<=A[hi]){
          return;}    
      }



  else{    // start scanning and swapping and recursing
      int pivot = low;    //the index of pivot

      while(len>1){  //  as long as the pivot is not at where it should be...scan and swap

         // pivot = low; // updating...unnecessary?

          while(pivot<hi){             // check on the right
              if (A[pivot]<=A[hi]){
                  hi--;
              }else{
                  break;
              }
          }

          if(A[pivot]>A[hi]){         //now swap pivot and hi;
              int holder=A[pivot];
              A[low]=A[hi];
              A[hi]=holder;

              pivot=hi;              // update pointers
              low++;
          }



          while(pivot>low){             // check on the left
              if (A[pivot]>=A[low]){
                  low++;
              }else{
                  break;
              }
          }

          if(A[pivot]<A[low]){         //now swap pivot and low;
              int holder=A[pivot];
              A[hi]=A[low];
              A[low]=holder;

              pivot=low;
              hi--;                   // update pointers
              }

      len = hi - low + 1;         // update len for the loop check

      }

      // now the pivot is in the right position...split and recurse.
      quicksort(A, 0, pivot-1);    // recurse on the left

      quicksort(A, pivot+1, A.length-1);  // recurse on the right

      } // the end of the else case.

}

3 个答案:

答案 0 :(得分:0)

据我所知,StackOverflow错误不能仅由无限循环引起...因为它不消耗内存。递归调用,所以我认为你的问题是你的算法有太多的递归调用(最后两次发生)。尝试更改基本情况以避免这种情况(例如,当长度小于10时使用另一种排序算法,或类似的东西)。

答案 1 :(得分:0)

这是因为您方法结束时的两次递归调用会再次对整个数组进行排序,而不是仅在lowhigh之间。您需要将递归调用限制在底端的low和顶端的high

答案 2 :(得分:0)

尝试将快速排序方法分解为多个小方法,之后将提高可读性。

此外,StackOverflow异常意味着堆栈已满,无法进行进一步的方法调用。查看代码中您调用方法的位置。我最后看到两个地方:

// now the pivot is in the right position...split and recurse.
quicksort(A, 0, pivot-1);    // recurse on the left

quicksort(A, pivot+1, A.length-1);  // recurse on the right

请调试在这些函数中传递的值是什么。

此外,如果您也可以粘贴测试用例的代码,那将是很好的。