堆排序是一种利用堆特性的选择排序,复杂度为 O(nlogn)
堆是一颗完全二叉树
堆排序的基本思想是:将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了
将数组映射为二叉树结构,对应关系如下
1 | @startuml |
# | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
---|---|---|---|---|---|---|---|---|---|
arr | 50 | 45 | 40 | 20 | 25 | 35 | 30 | 10 | 15 |
该数组从逻辑上讲就是一个堆结构,我们用简单的公式来描述一下堆的定义就是:
大顶堆:arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2]
小顶堆:arr[i] <= arr[2i+1] && arr[i] <= arr[2i+2]
下标与节点位置关系:
- 下标为 i 的节点父节点下标: (i-1)/2 整数除法
- 下标为 i 的节点的左孩子下标:i*2 + 1
- 下标为 i 的节点的右孩子下标:i*2 + 2
- 最后一个非叶子节点位置:(数组长度/2) - 1
最后一点是怎么得到的?隐隐记得之前看过的那本数据结构数上貌似有类似的答案。。。
实现
1 | public class HeapSort { |