堆是一个数组,它可以看作一个完全二叉树,树中的节点满足: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)