QuickSort(Java)实现溢出或停止

时间:2014-06-12 12:49:03

标签: java recursion quicksort

我一直在阅读所有关于SO的QuickSort问题,但我无法解决这个具体问题。通过引用其他问题并将我的错误与他们的错误进行比较,我得到了一个特定点,即使在调试模式下,我也找不到答案。

我一再超出界限-1,所以我添加了一个条件检查

if(pivot > 0)

并且停止了溢出,但由于我使用0作为我的分区,它分区一次然后终止。第一个分区是正确的,但是如果我将该数字更改为包含0,那么我将再次获得无限递归。如果我完全接受了这条线路,我会得到索引超出界限的错误,这些错误似乎无法解决。

这是我到目前为止的地方:

public class QuickSort {

int[] array;

public static void main(String[] args) {

    QuickSort qs = new QuickSort();
    qs.array = new int[] {35, 82, 2, 24, 57, 17};

    qs.quickSort(qs.array, 0, qs.array.length - 1);

    for(int i = 0; i < qs.array.length; i++) {

        System.out.println(qs.array[i]);

    }

}

public void quickSort(int[] array, int left, int right) {

    if(array.length == 1) {

        return;

    }

    if(left < right) {

        int pivot = partition(array, left, right);

        quickSort(array, left, pivot - 1);
        quickSort(array, pivot + 1, right);

    }

}

public int partition(int[] array, int left, int right) {

    if(array.length == 1) {

        return right;

    }

    int pivot = array[0];
    int pivotIndex = 0;
    int leftPointer = left - 1;
    int rightPointer = right + 1;

    while(pivotIndex < right) {

        if(leftPointer > rightPointer) {

            break;

        }

        leftPointer++;

        while(leftPointer < array.length - 1 && array[leftPointer] <= pivot) {

            leftPointer++;

        }

        rightPointer--;

        while(rightPointer > leftPointer && array[rightPointer] > pivot) {

            rightPointer--;

        }

        if(leftPointer < rightPointer) {

            int temp = array[leftPointer];
            array[leftPointer] = array[rightPointer];
            array[rightPointer] = temp;

        } else {

            int temp = array[rightPointer];
            array[rightPointer] = array[pivotIndex];
            array[pivotIndex] = temp;

        }

    }

    return rightPointer;

}

编辑:经过几次更改后,我现在可以让它始终返回一个没有溢出的数组,但它仍然只分区一次。

3 个答案:

答案 0 :(得分:0)

我认为你应该改变

 if(leftPointer > rightPointer) {
        break;
    }

 if(leftPointer >= rightPointer) {
        break;
    }

在while循环中。

此外,我认为你应该在更改之后将leftPointer与rightPointer进行比较,

    // move to @@@@ to perform compare after possible change
    // if(leftPointer > rightPointer)      break;


    //leftPointer++; 

    while(leftPointer < array.length - 1 && array[leftPointer] <= pivot) leftPointer++;


    //rightPointer--;  

    while(rightPointer > leftPointer && array[rightPointer] > pivot)   rightPointer--;


   //@@@@
   if(leftPointer > rightPointer) break;

答案 1 :(得分:0)

每当数组长度不为1时,您将从分区返回“0”,并将其设置为数据透视表。在这种情况下,if(pivot >= 0)将始终被点击,如果您使用if(pivot > 0),它将会迭代一次,我认为这是问题所在。如果这是正确的,那么纠正从分区返回(到“左”?)应该可以解决问题。

答案 2 :(得分:0)

我很确定我现在修好了。你想在之前增加分区方法中的左右指针(在“检查”之外)。按如下方式更改分区方法:

public static int partition(int[] array, int left, int right) {

  if(array.length == 1)
      return right;

  int pivot = array[0];
  int pivotIndex = 0;
  int leftPointer = left; // Remove the +1
  int rightPointer = right; // Remove the +1

  while(pivotIndex < right) {
      if(leftPointer > rightPointer) {
          break;
      }
    //leftPointer++;

      while((leftPointer < array.length - 1) && (array[leftPointer] <= pivot)) {
          leftPointer++;
      }
      //rightPointer--;

      while((rightPointer > leftPointer) && (array[rightPointer] > pivot)) {
          rightPointer--;
      }

      if(leftPointer < rightPointer) {
          int temp = array[leftPointer];
          array[leftPointer] = array[rightPointer];
          array[rightPointer] = temp;
      }
      else {
          int temp = array[rightPointer];
          array[rightPointer] = array[pivotIndex];
          array[pivotIndex] = temp;
      }
  }
  return rightPointer;

}