上文提到的leetcode第215题除了快速排序的二分partition解法,还可以用堆排序来解决,小小一道medium题居然汇集了快排和堆排这两位卧龙凤雏,实属难得。
数据结构-堆
完全二叉树
首先,堆是一棵完全二叉树,因此其具备完全二叉树的全部特点:
- 除了最后一层外,其余层的节点数都达到最大值,而最后一层的节点都集中在左边。
- 节点的编号与其对应的满二叉树中节点编号相同
- 若最后一个非叶子节点的编号为
i
,则编号0~i
的节点都是非叶子节点,编号i+1~n-1
的节点都是叶子节点 - 若一个非叶子节点的编号为
i
,则它的两个子节点的编号分别为2i+1
、2i+2
- 对于总节点数为
n
的完全二叉树,其最后一个非叶子节点的编号为n/2 - 1
,原因:最后一个非叶子节点是最后一个叶子节点(编号n - 1
)的父亲,根据第4点可得n - 1 = 2i + 1
或者n - 1 = 2i + 2
,计算取整出来都得到i = n/2 - 1
- 根据第3点和第5点,可得第一个叶子节点的编号为
n/2
下图中,红色数字即为完全二叉树中节点的编号
堆
在完全二叉树的基础上,堆还有具有以下性质:每个节点的值都大于等于其左右子节点的值,这是大根堆;每个节点的值都小于等于其左右子节点的值,这是小根堆。
大根堆: a r r [ i ] > = a r r [ 2 i + 1 ] & & a r r [ i ] > = a r r [ 2 i + 2 ] arr[i] >= arr[2i+1]\ \&\&\ arr[i]>=arr[2i+2] arr[i]>=arr[2i+1] && arr[i]>=arr[2i