堆是一个数组,它可以看作一个完全二叉树,树中的节点满足:parent(i) >= left(2i), parent(i) >=right(2i+1)或者parent(i) <= left(2i), parent(i) <=right(2i+1), 前者被成为大顶堆,后者被称为小顶堆。

维护堆的性质:
假设A的左子树和右子树满足堆的性质,但是插入结点i之后,有可能会破坏堆的性质,通过找到结点(i, 2i, 2i+1)中的最大值,让结点i与之交换,把结点i逐层下放来维护堆的性质。

def max_heapify(alist, i):
   """ i从0开始""
    lc = 2 * i + 1
    rc = 2 * i + 2
    n = len(alist)-1

    largest = i
    if lc <= n:
        if alist[lc] > alist[i]:
            largest = lc

    if rc <= n:
        if alist[rc] > alist[largest]:
            largest = rc

    if largest != i:
        alist[i], alist[largest] = alist[largest], alist[i]
        max_heapify(alist, largest)

创建堆
自底向上创建堆,根据堆的性质可知,树中大于n/2(n为树的结点个数)的结点都是叶结点。叶结点可以看作一个独立的堆,所以从n/2结点开始逐个递减,每加入一个新的结点,就需要重新维护堆的性质,直到结点降为0结束。

def build_heap(alist):
    n = len(alist)-1
    for i in range(int(n/2)+1, -1, -1):
        max_heapify(alist, i)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值