算法-大顶堆和小顶堆
堆可以看成是一个完全二叉树。
大顶堆:如果该完全二叉树满足双亲结点大于等于孩子节点,则这样的堆,称之为大顶堆。
小顶堆:如果该完全二叉树满足双亲结点小于等于孩子节点,则这样的堆,称之为小顶堆。
对于一个由二叉树生成的大顶堆或小顶堆(完全二叉树),若堆中的一个非叶子节点对应数组的下标索引为index,则这个节点的左右子节点和index有如下对应关系:
左节点:left = 2 * index + 1;
右节点:right = 2 * index + 2;
数组生成大顶堆
非叶结点index > 左结点:2 * index + 1
非叶结点index > 右结点:2 * index + 2
从最后一个非叶结点开始生成大顶堆。最后一个非叶结点:(len - 1)/2
或len/2 - 1
。
代码实现
1 | private void buidMaxHeap(int[] array) { |
示例
对于如下的一个无序数组:
1 | int[] arr = new int[]{9,6,8,7,0,1,10,4,2}; |
通过构建大顶堆,输出结果如下:
1 | 10,7,9,6,0,1,8,4,2 |
对应的堆结构变化如下:

生成后:

数组生成小顶堆
小顶堆的生成和大顶堆类似,特点如下:
非叶结点index < 左结点:2 * index + 1
非叶结点index < 右结点:2 * index + 2
从最后一个非叶结点开始生成大顶堆。最后一个非叶结点:(len - 1)/2
或len/2 - 1
。
代码实现
1 | private void buidMinHeap(int[] array) { |
示例
对于如下的一个无序数组:
1 | int[] arr = new int[]{9,6,8,7,0,1,10,4,2}; |
通过构建大顶堆,输出结果如下:
1 | 0,2,1,4,6,8,10,9,7 |
对应的堆结构变化如下:

生成后:

应用
topN
对于大顶堆来说,前N位就是数组中最大的N个数,对于小顶堆来说,前N位就是数组中最小的N个数。
堆排序
升序:需要构建大顶堆,即根节点为最大的结点,交换根节点和最后一个元素,即可生成升序数组。
1
2
3
4
5
6
7
8
9
10
11
12
13
14public void ascHeapSort(int[] array) {
int len = array.length;
if(array == null || len = 1) {
return;
}
buildMaxHeap(array);
while(len > 0) {
swap(array, 0, len - 1);
len--;
maxHeap(array, len, 0);
}
}降序:需要构建小顶堆,即根节点为最小的结点,交换根节点和最后一个元素,即可生成降序数组。
1
2
3
4
5
6
7
8
9
10
11
12
13
14public void descHeapSort(int[] array) {
int len = array.length;
if(array == null || len = 1) {
return;
}
buildMinHeap(array);
while(len > 0) {
swap(array, 0, len - 1);
len--;
minHeap(array, len, 0);
}
}