堆是一棵顺序存储的完全二叉树。
其中每个结点的关键字都小于等于其孩子结点的关键字,这样的堆称为小根堆。
其中每个结点的关键字都大于等于其孩子结点的关键字,这样的堆称为大根堆。
举例来说,对于n个元素的序列{R1, … , Rn}当且仅当满足下列关系之一时,称之为堆:
Ri <= R2i+1 且 Ri <= R2i+2 (小根堆)
Ri >= R2i+1 且 Ri >= R2i+2 (大根堆)
其中i=1,2,…,n/2向下取整;
思想:将序列构造成初始堆,交换a[0]和a[n],重新生成堆,直至交换a[0]与a[1]为止。
public class DemoApplication {
public static void main(String[] args) {
int arr[] = {6, 4, 20, 9, 44, 11, 0,2,23,10,17,3};
//堆排序
stackSort(arr);
for(int k = 0; k < arr.length; k++){
System.out.print(arr[k] + ",");
}
}
/**
* 堆排序
*/
public static void stackSort(int arr[]) {
//初始化堆,构造大根堆
for(int i = (arr.length >> 1) - 1; i >=0; i--){
heapAdjust(arr, i, arr.length);
}
for(int i = arr.length - 1; i > 0; i--){
int tmp = arr[0];
arr[0] = arr[i];
arr[i] = tmp;
heapAdjust(arr, 0, i);
}
}
public static void heapAdjust(int arr[], int parent, int n){
int tmp = arr[parent];
int child = (parent << 1) + 1;
while(child < n){
//若有右孩子且右孩子比左孩子大
if(child + 1 < n && arr[child + 1] > arr[child]){
child++;
}
if(tmp >= arr[child]){
break;
}
arr[parent] = arr[child];
parent = child;
child = (parent << 1) + 1;
}
arr[parent] = tmp;
}
}