用于python 3的heapsort编码

时间:2013-12-03 03:30:01

标签: python python-3.x heapsort

def heapSort(lst):

    heap = arrayHeap.mkHeap(len(lst), arrayHeap.less)
    alst = list(lst)
    while alst != []:
        v = alst.pop(0)
        arrayHeap.add (heap, v)

    while heap.size != 0:
        w = arrayHeap.removeMin(heap)
        alst.append(w)
    return last

这是一个有效的堆排序函数吗?

1 个答案:

答案 0 :(得分:1)

假设您的arrayHeap提供与stdlib的heapq或任何其他合理的堆实现相同的保证,那么这是一个有效的堆排序,但它是一个非常愚蠢的

通过将原始序列复制到列表中然后从左侧弹出,您正在为O(N log N)排序做O(N ^ 2)准备。

如果你从右边那边改变它,那么你只做O(N)准备,所以整个事情需要O(N log N),作为一个heapsort应该。

话虽如此,我无法理解你为什么要弹出列表而不是迭代它。或者,就此而言,为什么要将原始序列复制到列表中而不是直接迭代它。如果你这样做,它会更快,只使用一半的内存,并且代码更简单。像这样:

def heapSort(lst):
    heap = arrayHeap.mkHeap(len(lst), arrayHeap.less)
    for v in lst:
        arrayHeap.add(heap, v)
    alst = []
    while heap.size:
        w = arrayHeap.removeMin(heap)
        alst.append(w)
    return last

使用一个稍微好一点的API,就像stdlib的heapq模块中的那个(顺便说一句,你有没有使用它的原因?),你可以使这更简单:

def heapSort(lst):
    alst = []
    for v in lst:
        heapq.heappush(alst, v)
    return [heapq.heappop(alst) for i in range(len(alst))]

...或者,如果你确定lst是一个列表,你不介意改变它:

def heapSort(lst):
    heapq.heapify(lst)
    return [heapq.heappop(lst) for i in range(len(lst))]

...或者,当然,您可以复制lst然后改变副本:

def heapSort(lst):
    alst = lst[:]
    heapq.heapify(alst)
    return [heapq.heappop(alst) for i in range(len(alst))]

您可能会注意到第一个是heapq文档中Basic Examples的第一个。