我首先使用java编写了快速排序的分区函数:
public static int partition(int[] array, int left, int right) {
int pivot = array[left];
int i = left;
int j = right;
while(i < j) {
while(i < j && array[j--] >= pivot); // flag1
if(i < j) array[i++] = array[j];
while(i < j && array[i++] <= pivot); // flag2
if(i < j) array[j--] = array[i];
}
array[i] = pivot;
return i;
}
然后我测试了该函数,但发现使用快速排序函数时输入数组不会改变。我怀疑flag1
和flag2
中的代码,然后我更改了它们:
public static int partition(int[] array, int left, int right) {
int pivot = array[left];
int i = left;
int j = right;
while(i < j) {
while(i < j && array[j] >= pivot)
j--;
if(i < j) array[i++] = array[j];
while(i < j && array[i] <= pivot)
i++;
if(i < j) array[j--] = array[i];
}
array[i] = pivot;
return i;
}
这次有效。为什么第一个代码片段不起作用?
答案 0 :(得分:5)
while(i < j && array[j--] >= pivot); // flag1
无论条件的第二个条款是否为真,都会改变j。
while(i < j && array[j] >= pivot)
j--;
如果条件的第二个子句为真,则仅更改j。
因此,这些做的事情完全不同。
考虑差异的影响:您正在寻找array
element < pivot
的最后一个元素。 j
指向该元素时,条件变为false。
j
仍然指向该元素。j
最终指向前一个元素;