一.堆排序简介
堆排序(英语:Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点
1.什么是堆?
堆是具有以下性质的完全二叉树
- 堆中某个节点的值总是不大于或不小于其父节点的值;
- 堆总是一棵完全二叉树。
2.堆排序中会用到的几个公式
这些公式,实质上是顺序存储二叉树的公式
- 第n个元素的左子节点为 2 * n + 1
- 第n个元素的右子节点为 2 * n + 2
- 第n个元素的父节点为(n - 1) / 2
二.算法思路
- 首先需要模拟数组为一个顺序存储二叉树(数组索引不变)
- 开始从最后一个非叶子节点开始,以从右到左,从下到上的的顺序开始对每个子树构建大顶堆
- 在构建后一个大顶堆后,此时交换堆顶元素和最后一个元素,这是就将最大元素沉到了数组末端,然后进行第二次递归,但是数组最后一个索引每次- 1
1.顺序存储二叉树中的最后一个非叶子节点怎么找?
顺序存储二叉树中的最后一个非叶子节点的叶子节点的叶子节点有两种情况.
1.最后一个非叶子节点只有一个叶子节点
这种情况下,这唯一的一个叶子节点就是数组最后一个元素根据文章开头的公式: (设 i 是最后一个非叶子节点的索引值)
(2 * i) + 1 = arr.length - 1 => i = ( arr.length / 2)- 1
2.最后一个非叶子节点有两个叶子节点
这种情况下,这两个非叶子节点就是倒数第一个和倒数第二个数字
此时,最后一个元素是右子节点
(2 * i) + 2 = arr.length - 1 => i = (arr.length / 2) - 1.5
此时,倒数带二个元素是左子节点
(2 * i) + 1 = arr.length - 2 => i = (arr.length / 2) - 1.5
由于是整形的所以,1.5就是1
得出(arr.length/2) - 1就是最后一个非叶子节点
3.算法图示
三.代码实现
import java.util.Random;
/**
* @Author: LySong
* @Date: 2020/3/14 14:25
*/
public class HeapSort {
public static final