一 堆定义
堆(Heap)是计算机科学中一类特殊的数据结构的统称。堆通常是一个可以被看做一棵完全二叉树的数组对象。如下所示:
二 堆的性质
假设堆是使用数组进行存储的,那么对于堆中的节点 i ,其对应的相关性质如下:
PARENT(i) = i / 2 // 父节点计算
LEFT(i) = i * 2 // 左孩子节点计算
RIGHT(i) = i * 2 + 1 // 右孩子节点计算
三 最大堆和最小堆
3.1 最大堆性质
最大堆的简单概括就是堆中任意一个节点的父节点,都比该任意节点的值要大。即:
PARENT(i) >= i
3.2 最小堆性质
最小堆的简单概括就是堆中任意一个节点的父节点,都比该任意节点的值要小。即:
PARENT(i) <= i
注:此处只讨论最大堆,最小堆的相关情况可以类推
四 最大堆性质维护
根据最大堆的性质,设计性质维护算法思想是:比较要调整的节点,以及该节点的左右孩子节点,找出这三个节点中的最大值,放到父母节点位置。如果进行了调整,就继续递归调用进行调整,如果没有进行交换,即当前要调整的节点就是最大节点,那么递归退出。所以该算法的时间复杂度为O(lgn),空间复杂度为O(1), 算法伪代码如下:
MAX_HEAPIFY(A, i)
l = LEFT(i)
r=RIGHT(i)
if l <= A.heapsize and A[l] > A[i]
largest = l
else
largest = i
if r <= A.heapsize and A[r] > A[largest]
largest = r
if largest != i
exchange A[i] and A[largest]
MAX_HEAPIFY(A, largest)
五 建立最大堆
建立最大堆的算法是通过利用维护最大堆性质的算法实现的。首先,给定一组数据,通过数组存储。此时,数组的后半段,即下标为A.length / 2 以后的位置,都会存储建立好的堆的叶子节点,所以我们的算法就是调整数组中的数的位置,然后让数组中的数据的顺序符合最大堆的性质。算法时间复杂度为 O(lgn), 空间复杂度为 O(1), 调整的算法如下:
BUILD_HEAPIFY(A)
A.heapsize = A.length
for i = ⌊A.length / 2⌋ to 0
MAX_HEAPIFY(A, i)
六 堆排序算法
首先对数组建立一个最大堆,然后每次获取最大堆的根节点存储到数组的最后位置,然后对剩余的数再进行上述操作,即可得到排序好的结果。算法实现的时间复杂度为 O(nlgn) , 空间复杂度为 O(1),算法伪代码如下:
HEAPSORT(A)
BUILD_HEAPIFY(A)
for i = A.length to 2
exchange A[1] and A[i]
A.heapsize = A.heapsize - 1
MAX_HEAPIFY(A, 1)