【问题标题】:How to divide an heap into two sub-heap with heapify for heapsort?如何使用 heapify 将一个堆分成两个子堆进行堆排序?
【发布时间】:2017-11-03 15:12:11
【问题描述】:

我正在尝试在 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 划分为左树和右树的任何想法?

【问题讨论】:

  • 什么是“辅助功能”?
  • 我在网上看到的所有 heapify 版本都是基于一个函数,将数组转换为堆。所以我调用了 fixHeap 辅助函数,但基本上是一个简单的 def 函数
  • 辅助,抱歉

标签: python recursion divide heapsort


【解决方案1】:

首先,fixheap 中缺少一些内容。假设节点 v 只有一个(左)子节点,那么getMaxKnot 将触发无效索引错误,因为j 将指向A 数组的末尾之外。

我个人认为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)

【讨论】:

  • 最后我自己解决了。基本上一个错误是我在考虑如何划分左树和右树,比如将我的堆拆分为 2 个子列表。相反,只需要使用递归调用 heapify 给右儿子和左儿子。我的第二个错误是在 heapify 中,按照您的提示进行改进后,我忘记插入条件“仅当父级大于儿子时才进行交换”。谢谢!
猜你喜欢
  • 2015-01-14
  • 2022-07-05
  • 2013-05-13
  • 2017-12-15
  • 1970-01-01
  • 2020-06-27
  • 2021-08-11
  • 2011-06-17
  • 2018-07-10
相关资源
最近更新 更多