我基于pivot编写了一个简单的分区数组实现。为简单起见,将数组中的第一个元素作为pivot元素。以下是我写的代码
public static void partitionOnPivot(int[] a , int lo , int hi)
{
int pivot = lo;
while (lo < hi)
{
while(a[lo] <= a[pivot]) lo++;
while(a[hi] > a[pivot]) hi--;
if(lo < hi) //we are already done with these cases
{
ArrayUtil.swap(a, lo++, hi--);
}
}
ArrayUtil.swap(a, pivot, lo);
}
现在对于下面的数组,
{26,84,98,45}
同时,lo
和hi
都将位于索引1。
此时26与84交换,输出变为{84, 26, 98, 45}
。 26应该一个人待着。
我已经做了很长时间的改变而没有任何进展。我们如何处理这个角落案件?程序中是否有任何错误?
答案 0 :(得分:0)
在外部while循环结束时使用此语句
ArrayUtil.swap(a, pivot, hi);
答案 1 :(得分:0)
ArrayUtil.swap(a, lo++, hi--);
是您不受欢迎的行为蔓延的地方,我打赌。因为++
是后增量,所以你用你的枢轴交换高元素,然后递增枢轴。
答案 2 :(得分:0)
“在某一点上,lo和hi都将站在索引1” - &gt;错误 从您编写的程序中可以清楚地知道,lo将位于索引1处,而hi将位于索引0处。因此,将跳过以下if条件,并且将执行最后一行交换两个索引处的值
if(lo < hi) //THE FOLLOWING STATEMENT WILL BE SKIPPED
{
ArrayUtil.swap(a, lo++, hi--);
}
结果数组为{84,26,98,45}。这正是你得到的。您应该进行以下更改
while(a[lo] <= a[pivot]) lo++;
while(a[hi] > a[pivot]) hi--;
变为
while(a[lo + 1] <= a[pivot]) lo++;
while(a[hi - 1] > a[pivot]) hi--;
还有其他人指出尝试改变
ArrayUtil.swap(a, lo++, hi--);
到
ArrayUtil.swap(a, lo, hi);
P.S我认为增量和减量运算符是邪恶的。在使用它们时,必须真正关注后/前行为。尽量避免使用它们。