一、堆排序是什么?
基于二叉树的二叉堆的排序算法。给定一个任意数组,不创建任何的额外空间,就在这个数组上进行排序。堆排序是一个稳定的O(nlogn)时间复杂度的算法。
二、分析 与 实现
1.思路
- 任意数组其实可以看作是一个完全二叉树,我们首先将其调整称为最大堆(根节点>=所有的子节点,子树也满足最大堆的定义),也就是堆化heapfiy。
- 从最后一个非叶子节点开始进行sift Down操作。
- sift Down操作就是从当前二叉树中最后一个小子树开始调整,将当前子树不断调整为最大堆,最终走到树根时,左右子树已经全部为最大堆,只需下沉根节点就能得到到最终的最大堆。
- 当sift Down操作完成后此时的堆已经是一个最大堆,我们只需要不断地交换堆顶元素和最后一个元素的位置,将堆顶元素继续进行sift Down操作,这样最大值就放在了数组的末尾。
- 走完整个循环,数组已经是一个升序的数组。
2.分析
- 最后一个非叶子结点就是最后一个叶子节点的父节点。
- 假设此时结点的索引为 i ,且它存在父子结点。
- 那么它父节点的索引为:(i - 1) / 2 ;
- 左子树的结点为:(2 * i) + 1;
- 右子树的结点为:(2 * i) + 2;
- 堆化时是从最后一个非叶子节点开始进行siftDown操作,而将最大值放在数组末尾时 是从堆顶元素开始的sift Down操作。
- arr.length - 1代表的是最后一个叶子节点,最后一个叶子节点再-1 / 2就是它的父节点。此时我们开始堆化的操作调整为最大堆。
- 需要注意的是两个sift Down操作的位置不同,一个是从最后一个非叶子结点开始的最大堆化,一个是从堆顶开始的将堆顶最大值先交换到末尾,然后数组长度–,再进行sift Down操作,将一个新的最大值放到堆顶。
2.代码实现
代码如下:
public class SevenSort {
public static void main(String[] args) {
int[] arr = {
19,27,