顾名思义,堆排序就是利用堆来排序。把待排序的数组,构建成堆,再进行排序。
1.堆
堆实际上是一棵完全二叉树,其任何一非叶节点满足性质:
小顶堆Data[i]<=Data[2i+1]&&Data[i]<=Data[2i+2] 或者 大顶堆Data[i]>=Data[2i+1]&&Data>=key[2i+2]
堆一般用数组来表示.如果根节点在数组中的位置是1, 第n个位置的子节点分别在2n和 2n+1.因此,第1个位置的子节点在2和3,第2个位置的子节点在4和5.以此类推.这种基于1的数组存储方式便于寻找父节点和子节点
2.堆排序的思想
利用大顶堆(小顶堆)堆顶记录的是最大关键字(最小关键字)这一特性,使得每次从无序中选择最大记录(最小记录)变得简单。
其基本思想为(大顶堆):
1)将初始待排序数组构建成大顶堆;
2)将堆顶元素Data[1]与最后一个元素Data[n]交换,此时得到新的无序数组Data[1]~Data[n-1] 和 Data[n];
3)由于交换后新的堆(Data[1]~Data[n-1])可能违反堆的性质,因此需要对当前无序区调整为新堆,然后再次将Data[1]与堆(Data[1]~Data[n-1])最后一个元素交换,得到新的无序区Data[1]~Data[n-2]和新的有序区Data[n-1]~Data[n]。不断重复此过程直到有序区的元素个数为n-1,则整个排序过程完成。
操作过程如下:
1)初始化堆:将Data[1~n]构造为大顶堆;
2)将当前无序区的堆顶元素Data[1]同该区间的最后一个记录交换。
3)重复1) 、2) 步骤
package sort;
public class HeapSort {
public static void main(String[] args) {
double[] temp = {12.0, 32.0, 3.0, 2.0, 54.0, 23.0, 43.0, 76.0, 44.0, 54.0, 43.0, 13.0};
double[] array = new double[20];
int size = temp.length;
//初始化堆,下表从1开始;假如当前节点的下标是n,左孩子节点坐标是2*n,右孩子节点坐标是2*n+1
for(int i = 0; i<size ; i++){
array[i+1] = temp[i];
}
//构建大顶堆
buildHeap(array, size);
//调用堆排序算法
sortHeap(array, size);
//打印排序后的数组
print(array,size);
}
private static void print(double[] array ,int size) {
for(int i=1; i<=size; i++){
System.out.print(array[i] + " ");
}
}
private static void adjustHeap(double[] array, int size, int i) {
int lchild = 2 * i; //left child
int rchild = 2 * i + 1; //right child
int max = i;
double maxValue;
//if is right node, skip this node(is the current max value)
if(size % 2 != 0){
size--;
}
if(array[max] <= array[lchild] && lchild <= size){
max = lchild;
}
if(array[max] <= array[rchild] && rchild <= size){
max = rchild;
}
//find the max value
if(i != max){
maxValue = array[i];
array[i] = array[max];
array[max] = maxValue;
}
}
//构建大顶堆
private static void buildHeap(double[] array, int size) {
for(int i = size/2 ;i > 0; i--){
adjustHeap(array, size, i);
}
}
//堆排序算法
private static void sortHeap(double[] array, int size) {
double tempMax ;
for(int i = size; i > 1; i--){
tempMax = array[1];
array[1] = array[i];
array[i] = tempMax;
int temp = i - 1;
buildHeap(array, temp);
}
}
}