基于pivot的分区数组

时间:2012-01-16 11:56:21

标签: java algorithm sorting pivot quicksort

我基于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}

同时,lohi都将位于索引1。

此时26与84交换,输出变为{84, 26, 98, 45}。 26应该一个人待着。

我已经做了很长时间的改变而没有任何进展。我们如何处理这个角落案件?程序中是否有任何错误?

3 个答案:

答案 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我认为增量和减量运算符是邪恶的。在使用它们时,必须真正关注后/前行为。尽量避免使用它们。