1。首先明白一个概念,大根堆,小根堆是一种数据结构,堆排序是在大根堆或者小根堆这种数据结构上进行排序的一种排序算法。一个是数据结构,一个是算法。
2.最大堆常用来构建升序,最小堆常用来构建降序。
- 性质一: 索引为i的左孩子的索引是 (2*i+1);
- 性质二: 索引为i的右孩子的索引是 (2*i+2);
- 性质三:索引为i的父结点的索引是 floor((i-1)/2); 注:第一个元素的索引位0
3.堆排序的时间复杂度是O(N*logN),属于不稳定排序算法
4.大根堆的java排序代码如下
public class HeapSort {
public static void maxHeapDown(int[] a, int start, int end) {
//
int c = start; // 当前(current)节点的位置
int l = 2*c + 1; // 左(left)孩子的位置
int tmp = a[c]; // 当前(current)节点的大小
for (; l <= end; c=l,l=2*l+1) {
// "l"是左孩子,"l+1"是右孩子
if ( l < end && a[l] < a[l+1]) l++; // 子节点存在左右孩子,左右两孩子中选择较大者,用于后续直接交换,不存在就算了
//这里的l++增加之后不减的主要问题是若交换了父结点的值和l++的值,那么也会破坏下一层的堆结构,所以交换哪一个结点,下一个就去哪进行重建
if (tmp >= a[l]){ //如果父节点大于子节点,调整结束
break;
}else { // 否则 交换父和子
a[c] = a[l];
a[l]= tmp;
}
}
}
public static void heapSortAsc(int[] a, int n) {
int i,tmp; //n 数组长度
// 从(n/2-1) --> 0逐次遍历。遍历之后,得到的数组实际上是一个(最大)二叉堆。
for (i = n / 2 - 1; i >= 0; i--)
maxHeapDown(a, i, n-1);
// 从最后一个元素开始对序列进行调整,不断的缩小调整的范围直到第一个元素,获得最大值
for (i = n - 1; i > 0; i--) {
// 交换a[0]和a[i]。交换后,a[i]是a[0...i]中最大的。
tmp = a[0];
a[0] = a[i];
a[i] = tmp;
// 调整a[0...i-1],使得a[0...i-1]仍然是一个最大堆。
// 即,保证a[i-1]是a[0...i-1]中的最大值。
maxHeapDown(a, 0, i-1);
}
}