荷兰国旗排序

时间:2012-05-21 02:43:48

标签: python sorting

我正在尝试使用Dutch national flag algorithm编写quicksort-ish算法。我已经尽了一切努力使这项工作变得非常沮丧。你能看看并帮我找到错误吗?

import random

a = []
for i in range(100):
    a.append(random.randint(1, 100))

print(a)
def partion(array, left, right, lPiv, rPiv):
        high = len(array) -1
        p = left
        i = left
        while i < high:
                if array[i] < lPiv and array[i] < rPiv:
                        array[i],array[p]=array[p],array[i]
                        p = p+1
                        i = i+1
                elif array[i] > lPiv and array[i] > rPiv:
                        array[i],array[high]=array[high],array[i]
                        high = high-1
                else:
                        i = i+1

        return [p, high]

def piv(array, left, right):
    aMin = array[left]
    aMax = array[left]

    for i in array:
      if i < aMin:
          aMin = i
      if i > aMax:
          aMax = i
    return [aMin + ((aMax - aMin) /3), aMin + ((aMax-aMin)/3)*2]


def sort(array, left, right, depth):
    apiv = piv(array, left, right)
    part = partion(array, left, right, apiv[0], apiv[1])
    if right-left >= 3:
        piv1 = piv(array, left, part[0])
        part1 = partion(array, left, part[0], piv1[0], piv1[1])
        sort(array, left, part1[0], depth+1)


        piv2 = piv(array, part[0], part[1])
        part2 = partion(array, part[0], part[1], piv2[0], piv2[1])
        sort(array, part[0], part[1])

        piv3 = piv(array, part[1], right)
        part3 = partion(array, part[1], right, piv3[0], piv3[1] )
        sort(array, part[1], right)

    elif right-left < 3:
        if array[right] < array[left]:
            array[right],array[left] = array[left], array[right]
        else:
            return


sort(a, 0, len(a), 1)
print(a)

2 个答案:

答案 0 :(得分:1)

您的代码中存在一些错误

  1. sort()需要4个参数,因此sort(array,part [0],part [1])失败。 btw深度不是必需的。
  2. if array[right] < array[left]:sort(a, 0, len(a), 1)。 当数组长度为数组时,右数超出数组的索引范围。
  3. piv应该处理partion而不是整个数组
  4. 如果分区中的数字全部相同,aMin + ((aMax - aMin) /3)aMin + ((aMax-aMin)/3)*2是相同的索引
  5. 因为分区只处理分区而不是整个数组,high = len(array) -1应该是high = right -1
  6. part1 = partion(array, left, part[0], piv1[0], piv1[1])错了。 Sort()在它开始时对数组进行分区,不要在同一递归中分区两次。只需调用sort(array,...)。
  7. 您的分区分区算法错误,我找不到简单的修复方法

  8. 这是我的实施。

    import random
    from itertools import islice
    a = []
    for i in range(100):
        a.append(random.randint(1, 100))
    
    def partition(array, left, right, lPiv, rPiv):
            q = right -1
            p = left
            r = left
            while p<=q:
                if array[p]<=lPiv:
                    array[p], array[r] = array[r], array[p]
                    p = p+1
                    r = r+1
                elif lPiv<array[p]<=rPiv:
                    p = p+1
                else:
                    array[p], array[q] = array[q], array[p]
                    q=q-1
    
            return (p, q+1)
    
    def piv(array, left, right):
        aMin = min(islice(a,left,right))
        aMax = max(islice(a,left,right))
        return (aMin + ((aMax - aMin) /3.0), aMin + ((aMax-aMin)/3.0)*2)
    
    
    def sort(array, left, right):
        if right-left >= 3:
            piv_left, piv_right = piv(array, left, right)
            if piv_left == piv_right:
                return
            pt_left, pt_right = partition(array, left, right, piv_left, piv_right)
            sort(array, left, pt_left)
            sort(array, pt_left, pt_right)
            sort(array, pt_right, right)
        elif right-left <3:
            if left<right and array[right-1] < array[left]:
                array[right-1],array[left] = array[left], array[right-1]
    
    
    sort(a, 0, len(a))
    print a
    
    #test
    assert( a==sorted(a) )
    

答案 1 :(得分:0)

pic似乎总是返回相同的值,是吗?也许for循环应该在数组[left:right]上而不是在整个数组上?