我有以下两种方法:
public static void QuickAlgo(int[] a, int left, int right) {
int index = partition(a, left, right);
if (left < index - 1) {
QuickAlgo(a, left, index - 1);
}
if (index < right) {
QuickAlgo(a, index, right);
}
}
static int partition(int[] a, int left, int right) {
int pivot = a[(left + right) / 2];
while (left <= right) {
while (a[left] < pivot) {
left++;
}
while (a[right] > pivot) {
right--;
}
if (left <= right) {
int temp = a[left];
a[left] = a[right];
a[right] = temp;
left++;
right--;
}
}
return left;
}
假设我有以下问题的未排序数据:
_______________________________________
65 | 72 | 23 | 36 | 99 | 20 | 1 | 44 |
让我们说,我的支点是36
。
当调用partition
方法时,我理解它是
检查以下循环while(left <= right)
现在,对于以下代码段:
if (left <= right) {
int temp = a[left];
a[left] = a[right];
a[right] = temp;
left++;
right--;
}
不应该是这样的:
1)首先应将[left]与pivot进行比较,如我的例子65&gt;所示。 36因此 有资格换货。类似地,必须将枢轴与a [右]进行比较,在我的示例中,它是44,并且因为枢轴(36)&lt;在图44中,指针递减并移动到1,因此1有资格进行交换,因为枢轴(36)> 1。
虽然上面提到的代码片段是直接比较的 索引值和交换数字。
可能我在这里不理解。有人可以解释一下吗?
由于
答案 0 :(得分:1)
当你到达交换点时,与你提到的支点的比较已经完成。第一个while循环在找到大于pivot&amp;的值时结束。当第二个循环找到一个小于枢轴的值时结束。这意味着左和右右指针找到了一个错误的值,因此,这两个值都有资格进行交换。
if (left <= right)
仅用于确保在左光标通过右光标后不交换值。当左光标通过右光标时,表示分区已完成,因此不应再进行交换。
答案 1 :(得分:0)
我们这样做是为了确保枢轴左侧的所有元素都小于枢轴并且朝向枢轴的右侧大于枢轴。现在,如果你看到之前的两个while循环if(a [left]&lt; pivot)
它们将用于遍历元素从开始时小于枢轴的点,而另一个用于获取元素大于枢轴的结束。现在考虑:3 4 19 7 21 2作为我们的阵列,7是枢轴。这里我们将左= 2和右= 5 ...所以我们交换这两个元素。并且在左边进行分区,因为我们确定左边的所有元素都比左边小。