一、算法思想
堆排序是基于二叉树数据结构完成的。
首先,将连续的数组视为一个完全二叉树。
①将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的②根节点。将其与末尾元素进行交换,此时末尾就为最大值。然后将③剩余n-1个元素重新构造成一个堆,这样会得到n-1个元素的最大值,也就是n个元素的次大值。如此反复执行,便能得到一个有序序列了。
二、堆排序的优缺点
优点:
- 堆排序的效率与快排、归并相同,都达到了基于比较的排序算法效率的峰值(时间复杂度为O(nlogn))
- 除了高效之外,最大的亮点就是只需要O(1)的辅助空间了,既最高效率又最节省空间,只此一家了
- 堆排序效率相对稳定,不像快排在最坏情况下时间复杂度会变成O(n^2)),所以无论待排序序列是否有序,堆排序的效率都是O(nlogn)不变(注意这里的稳定特指平均时间复杂度=最坏时间复杂度,不是那个“稳定”,因为堆排序本身是不稳定的)
缺点:(从上面看,堆排序几乎是完美的,那么为什么最常用的内部排序算法是快排而不是堆排序呢?)
最大的也是唯一的缺点就是——堆的维护问题,实际场景中的数据是频繁发生变动的,而对于待排序序列的每次更新(增,删,改),我们都要重新做一遍堆的维护,以保证其特性,这在大多数情况下都是没有必要的。(所以快排成为了实际应用中的老大,而堆排序只能在算法书里面顶着光环,当然这么说有些过分了,当数据更新不很频繁的时候,当然堆排序更好些…)
三、源代码
import java.util.Arrays;
import java.util.Random;
/**
* Created by chengxiao on 2016/12/17.
* 堆排序demo
*/
public class HeapSort {
public static void main(String[] args) {
// int[] arr = {65, 80, 12, 23, 67, 49, 27};
int[] arr=new int[new Random().nextInt(9)+1];
for (