堆排序不工作python

时间:2016-12-12 09:18:38

标签: python sorting heapsort

参考麻省理工学院的开放课程软件算法第4章,我根据给出的伪代码创建了堆排序:

def heap_sort(A):
    build_max_heap(A)
    curr_heap_size = len(A)
    while curr_heap_size:
        A[0],A[curr_heap_size-1] = A[curr_heap_size-1],A
        curr_heap_size -= 1
        max_heapify(A,0)
    return A

build_max_heap保证是正确的,因为我用pythons heapq库检查了它。

但是,heap_sort似乎无法正常工作,

test_array = [1,5,3,6,49,2,4,5,6]
heap_sort(test_array)
print(test_array) # --> [6,5,5,4,3,49,6,2,1]

完全难倒在这里,我与Heap sort Python implementation交叉检查,看起来是一样的......

非常感谢帮助,谢谢!

编辑:max_heapify和build_max_heap的代码:

def max_heapify(A,i):
    heap_size = len(A)
    l,r = i*2+1,i*2+2
    largest = l
    if l < heap_size and A[l] > A[largest]:
        largest = l
    if r < heap_size and A[r] > A[largest]:
        largest = r
    if largest != i:
        A[i],A[largest] = A[largest],A[i]
        max_heapify(A,largest)

def build_max_heap(A):
    array_size = len(A)
    for i in range(array_size // 2 ,-1,-1):
        max_heapify(A,largest)

1 个答案:

答案 0 :(得分:0)

您的代码中存在一些错误,这些错误会使您的案例重新生成变得更加困难,并找到解决您特定问题的解决方案,但现在就可以了。

首先,您的代码在heap_sort函数中包含语法错误,特别是当您尝试交换A的第一个和最后一个元素时。在该赋值的右侧,第二个值为A,即使它应该是A [0]。

其次,您在build_max_heap中使用变量maximum意味着最大值是您在问题中未提供的全局变量声明,或者您打算使用i。我认为这是第二种情况,因为我根据你提供的代码有一个工作的heap_sort,我认为我的假设是正确的。

第三,在max_heapify中,您将最大值初始化为l,即使您应该使用i初始化它。我相信你会发现这是一个微不足道的错误,因为在同样的函数中,你明显期望最大的值等于i的值。

最后,你最关键的错误是你不断传递整个数组并使用永不减少的数组长度。(即它始终是test_array的初始长度)你使用的算法找到给定数组的最大元素并将其从结构的其余部分中排除。这样,你有一个数组,它的大小不断减小,同时将最大的元素发送到最后。(即超出它的范围/长度)但是,因为你永远不会减小数组的大小,并且它的长度连续计算为len(test_array),它将永远不会按预期工作。

有两种方法可以解决您的问题。选项1在heap_sort中传递给max_heapify更短版本的A.具体来说,你应该在循环的每次迭代中传递A [:curr_heap_size]。这种方法可以工作,但它并不是真正节省空间,因为每次都会创建一个新列表。相反,您可以将curr_heap_size作为参数传递给函数build_max_heap和max_heapify,并假设它是长度。 (即与len(A)相反)

下面是一个有效的heap_sort实现,基于您的代码。我所做的就是解决上面列出的错误。

def max_heapify(A, heap_size, i):
    l,r = i*2+1,i*2+2
    largest = i
    if l < heap_size and A[l] > A[largest]:
        largest = l
    if r < heap_size and A[r] > A[largest]:
        largest = r
    if largest != i:
        A[i], A[largest] = A[largest], A[i]
        max_heapify(A, heap_size, largest)

def build_max_heap(A, array_size):
    for i in range(array_size // 2 ,-1,-1):
        max_heapify(A, array_size, i)

def heap_sort(A):
    curr_heap_size = len(A)
    build_max_heap(A, curr_heap_size)
    while curr_heap_size > 0:
        A[0], A[curr_heap_size-1] = A[curr_heap_size-1], A[0]
        curr_heap_size -= 1
        max_heapify(A, curr_heap_size, 0)
    return A