堆排序
利用数据结构最大堆和最小堆进行排序操作。升序排序利用最大堆,降序排序利用最小堆。
基本思路(升序为例)
初始化堆:将数列a[1…n]构造成最大堆。
交换数据:将a[1]和a[n]交换,使a[n]是a[1…n]中的最大值;然后将a[1…n-1]重新调整为最大堆。 接着,将a[1]和a[n-1]交换,使a[n-1]是a[1…n-1]中的最大值;然后将a[1…n-2]重新调整为最大值。 依次类推,直到整个数列都是有序的。
数组实现二叉堆有以下性质(第一个数组元素索引值为0):
索引为i的左孩子的索引是 (2*i+1);
索引为i的左孩子的索引是 (2*i+2);
索引为i的父结点的索引是 floor((i-1)/2);
时间复杂度与稳定性
时间复杂度
堆排序的时间复杂度是O(N*lgN)。
堆排序是采用的二叉堆进行排序的,二叉堆就是一棵二叉树,它需要遍历的次数就是二叉树的深度,而根据完全二叉树的定义,它的深度至少是lg(N+1)。最多是多少呢?由于二叉堆是完全二叉树,因此,它的深度最多也不会超过lg(2N)。因此,遍历一趟的时间复杂度是O(N),而遍历次数介于lg(N+1)和lg(2N)之间;因此得出它的时间复杂度是O(N*lgN)。
稳定性
堆排序是不稳定性算法。在交换数据的时候,是比较父结点和子节点之间的数据,所以,即便是存在两个数值相等的兄弟节点,它们的相对顺序在排序也可能发生变化。
适用情况
对较大的序列排序,时间复杂度同快速排序、归并排序,特长所需辅助空间少,适合相对有序的序列排序。
堆排序实现
|
|
输出结果:

