快速排序逻辑

时间:2012-06-23 12:54:05

标签: sorting quicksort

我正在尝试在java中实现快速排序,我有一个疑问。所以这是我的快速排序代码:

package com.sorting;

public class QuickSort implements Sort {

@Override
public int [] sort(int[] arr) {
    return quickSort(arr, 0, arr.length - 1);
}

private int [] quickSort(int[] numbers, int low, int high) {

    if (low < high) {
        int q = partitionTheArrayAroundPivot(numbers, low, high);

        if (low < q)
            quickSort(numbers, low, q);

        if ((q+1) < high)
            quickSort(numbers, q + 1, high);
    }

    return numbers;
}

private int partitionTheArrayAroundPivot(int[] numbers, int low, int high) {

    int pivot = selectPivot(numbers, low, high);
    int i = low;
    int j = high;

    while (true) {

            while (numbers[i] < pivot) {
            i++;
        }

            while (numbers[j] > pivot) {
            j--;
        }

        if ( i <= j) {
            swap(numbers, i, j);
            i++;
            j--;
        } else {
            return j;
        }

    }

}

private int selectPivot(int[] numbers, int low, int high) {
    return numbers[high];
}

private void swap(int[] numbers, int i, int j) {
    int temp = numbers[i];
    numbers[i] = numbers[j];
    numbers[j] = temp;
}

}

怀疑1:我们一直在增加索引i,直到我们达到一个&gt; = pivot

的数字
while (numbers[i] < pivot)
    i++;

同样地,我们继续减少索引j,直到我们达到&lt; = pivot

的数字为止
while (numbers[j] > pivot)
    j--;

因此,这意味着如果两个命中都在两个不同的位置枢转,那么两个索引也将脱离循环,例如1,0,1这里如果pivot是1,那么我将是0而j将是2.并且以下条件将被满足     if(i&lt; = j){         ....     }     但是在那种情况下,它无法对上面的数组(1,0,1)进行排序,因为在交换之后我们正在增加i并减少j因此值变为i = j = 1.之后我会点击第三个元素,即1,将再次出现在循环中,值为i = 2,同样j = 0,我们将无法对数组进行排序。

那么问题出在哪里?我错过了什么吗?

2 个答案:

答案 0 :(得分:0)

我会稍微重写代码,以便selectPivot返回索引:

private int selectPivotIndex(int[] numbers, int low, int high) {
    return high;
}

然后分区功能可以将枢轴移到一边,并根据枢轴值对剩余项目进行排序。单个循环将执行此操作,在此实现中,重复的枢轴将在右侧结束:

private int partitionTheArrayAroundPivot(int[] numbers, int low, int high) {

    int pivotIndex = selectPivotIndex(numbers, low, high);

    swap(numbers, pivotIndex, high); // Not needed if selectPivotIndex always returns high
    int newPivotIndex = low;
    for(int i = low; i < high; i++)
    {
        if(numbers[i] < numbers[pivotIndex])
        {
            swap(numbers, i, newPivotIndex);
            newPivotIndex++;
        }
    }
    swap(numbers, newPivotIndex, pivotIndex);

    return newPivotIndex;
}

最后,需要在quickSort方法中进行小幅调整,以便我们不会在永恒的循环中结束:

if (low < q)
      quickSort(numbers, low, q - 1);

这种方法是恕我直言更容易理解和调试,希望它适合你。

答案 1 :(得分:0)

使用
while (numbers[i] <= pivot)while (numbers[j] >= pivot)并且您的代码可以使用