如何使用heapify将堆分成两个子堆用于heapsort?

时间:2017-11-03 15:12:11

标签: python recursion divide heapsort

我很想在python中创建一个HeapSort函数,使用一些辅助函数。

我正在尝试按照我的书籍说明,并使用fixHeap之类的函数来恢复堆中正确的顺序,并且节点不遵循规则:

def getMaxKnot(i,j,A):
    k = max(A[i],A[j])
    if k==A[i]:
        return i
    if k==A[j]:
        return j


def fixheap(v,H): #basically restore an heap with a node not following heap rules
    if (2*v+1)>len(H)-1:
        return H
    else:
        u=getMaxKnot(2*v+1,2*v+2,H)
        if H[u]>H[v]:
            listoperations.swap(u,v,H) #swap item in position u and v
        return fixheap(u,H)

现在,我基本上想要创建一个在左树和右树上递归工作的heapify函数,使用我的函数fixheap来恢复正确的顺序。

我的想法如下:

def heapify(A):
        if A==[]:
            return A
        else:
            heapify(LEFT TREE)
            heapify(RIGHT TREE)
            fixheap(0,A)

关于如何将我的阵列A划分为LEFT TREE和RIGHT TREE的任何想法?

1 个答案:

答案 0 :(得分:0)

首先,fixheap中缺少某些内容。想象一下,节点 v 只有一个(左)子节点,然后getMaxKnot将触发无效的索引错误,因为j将指向A的末尾} array。

就个人而言,我认为getMaxKnot不应该是一个单独的功能。我还将fixheap的参数放在相反的顺序中,这样第二个可以很容易地省略并给出一个默认值(当它是根元素时)。同时交换两个值实际上是一个单行:

def fixheap(H, v = 0): # put arguments in this order
    u = 2*v + 1
    if u >= len(H):
        return H
    if u+1 < len(H) and H[u+1] > H[u]: # Only compare when there are two child nodes
        u += 1
    if H[u] > H[v]:
        [H[u], H[v]] = [H[v], H[u]] # Swapping is easy
        return fixheap(H, u)

接着是你的主要问题:你的heapify也应该得到一个节点作为参数,这将是你想要堆积的子树的根。事实上,该原则与fixheap函数的使用方式没有太大区别:

def heapify(H, v = 0):
    u = 2*v + 1
    if u >= len(H):
        return H
    heapify(H, u)
    if u + 1 < len(H): # make sure there is a right child
        heapify(H, u+1)
    fixheap(H, v)