就地分区不适用于重复元素

时间:2012-03-28 07:09:59

标签: python algorithm quicksort data-partitioning

我试图实现quicksort的就地分区子程序。它使用唯一元素数组,但是当数组包含重复元素时失败

代码就像这样

def inplace_partitioning(input,l,r):
    len_a=len(input)
    pivot=input[l]
    i=l+1
    for j in range(l+1,r+1,1):
        if input[j]<pivot:#do nothing if new elem >pivot
            #swap new elem with leftmost elem greater than pivot
            temp=input[j]
            input[j]=input[i]
            input[i]=temp
            i+=1
    #swap pivot with rightmost elem lessthan pivot
    temp=input[l]
    input[l]=input[i-1]
    input[i-1]=temp

当输入具有唯一元素时,代码会给出正确的结果

input=[5,6,3,1,8,4]
inplace_partitioning(input,0,len(input)-1)
print input

>>[4, 3, 1, 5, 8, 6]

当我尝试下面的数组时,我得到了错误的结果

input=[5,6,3,1,8,5]
>>>[1, 3, 5, 6, 8, 5]

这是因为我的实施有问题吗?有人会帮忙吗?

3 个答案:

答案 0 :(得分:0)

if input[j]<pivot:

这意味着如果它们更小,它只会移动枢轴左侧的数字。 但是,您希望数字等于要移动的枢轴大小,否则与枢轴相同大小的数字将遍布枢轴右侧。

将其更改为:

if input[j]<=pivot:

答案 1 :(得分:0)

我不太了解你的算法,它看起来不像快速分区。通常情况下,你在不同的方向上运行i和j,一个从区间的顶部开始,一个在底部,但如果我理解正确,你的运行方向相同。在第一次迭代中,i和j具有相同的值,如果它小于枢轴,则它会自行交换(即,它的效果就像它不小于枢轴一样)?

答案 2 :(得分:0)

这应该这样做

def partitionv(arr, l, r):

    p = r
    idx = l
    for i in range(l, r-1, 1):
        if arr[i] < arr[p]:
            arr[i], arr[idx] = arr[idx], arr[i]
            idx += 1
    arr[p], arr[idx] = arr[idx], arr[p]

    return arr

这是右侧元素的分区。