在quicksort中为什么我们在数组外开始减量

时间:2014-02-19 21:52:49

标签: java quicksort

public class QuickSort {
    public static void sort(int[] a) {
        StdRandom.shuffle(a);
        sort(a, 0, a.length - 1);
    }

    private static void sort(int[] a, int left, int right) {
        if (right <= left) {
            return;
        }
        int j = partition(a, left, right);      
        sort(a, left, j - 1);
        sort(a, j + 1, right);
    }

    private static int partition(int[] a, int left, int right) {
        int i = left;
        int j = right+1;
        int pivot = a[left];
        while (true) {
            while (a[++i] < pivot) {
                if (i == right) {
                    break;
                }
            }
            while (a[--j] > pivot) {
                if (j == left) {
                    break;
                }
            }
            if (i >= j) {
                break;
            }
            swap(a, i, j);
        }
        swap(a, left, j);
        return j;
    }

    private static void swap(int[] a, int i, int j) {
        int temp = a[i];
        a[i] = a[j];
        a[j] = temp;

    }

    public static void main(String[] args) {
        int[] a = { 5, 3, 1, 34, 43, 5454};
        QuickSort.sort(a);
        show(a);

    }

    private static void show(int[] a) {
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i] + " ");
        }

    }
}

在此示例中,int j = right+1在数组外部开始,因此我们按a[--j]递减

当我将其更改为int j = right并递减a[j--]时,输出结果不同。可能是一些简单的事情,但在过去的一小时里一直很困惑。我不明白为什么我们不只是从数组的最后一个索引开始递减,例如:

{4,3,6,1,9}

int j = right 

所以j = array[4]然后我们说while... array[4--]会变成j=array[3]对吗?

不是同一件事:right+1 and --jright and j--

2 个答案:

答案 0 :(得分:3)

行:

while (a[--j] > pivot) {
    if (j == left) {
        break;
    }
}

期望j的两个值相同。如果将其更改为

while (a[j--] > pivot) {
    if (j == left) {
        break;
    }
}

第一个引用的j,a[j--]将比下一个j j == left

高一个

如果您想进行更改,则必须将其更改为:

while (a[j--] > pivot) {
    if (j+1 == left) { //adding one back in
        break;
    }
}

我个人认为之前的代码更清晰,因为在范围之外启动代码是常见且可理解的。添加一个是'繁琐',将使每个人质疑它是否正确。

进行更改的最明确方法可能是:

while (a[j] > pivot) {
    if (j == left) {
        break;
    }
    j--; // waiting until the end to decrement
}

我会认为这很干净,而且比原始版本更好,因为你从int j = right开始。

答案 1 :(得分:1)

将j的值与循环中的其他位置进行比较。如果计数器以j = right开头,则在使用--jj--递减j后,这些点的j值将与您从j = right+1 <开始时的值不同/ p>