前置知识(数组实现堆):
- 堆结构特(以大根堆为例),根节点的值最大,任何一个子树的最大值在顶部
- 下标为i的父节点在数组中的位置为:(i-1)/2;
- 下标为i的左孩子在数组中的位置为: i*2+1,下标为i的右孩子在数组中的位置为: i*2+2;
堆的向上调整:
public static void heapInsert(int[]arr,int i){
while(arr[i]>arr[(i-1)/2]){
swap(arr,i,(i-1)/2);
i = (i-1)/2;
}
}
堆的向下调整:
public static void heapify(int[]arr,int i,int size){
int l = i*2+1;
while(l<size){
int best = l+1<size&&arr[l+1]>arr[l]?l+1:l;
best = arr[best]>arr[i]?best:i;
if(best==i)break;
swap(arr,best,i);
i = best;
l = i*2+1;
}
}
堆排序的实现就是对堆的向上与向下调整
过程:给定一个arr数组,先用heapInsert变成大根堆,再让最后一个位置的元素与0下标位置交换,让后size--用heapify维护大根堆,当size==1时最后数组变有序。
public static void heapSort(int[] arr){
int n = arr.length;
for(int i=0;i<arr.length;i++){
heapInsert(arr,i);
}
int size = n;
while (size>1){
swap(arr,--size,0);
heapify(arr,0,size);
}
}
public static void swap(int[] arr,int x,int y){
int temp = arr[x];
arr[x] = arr[y];
arr[y] = temp;
}
全部代码:
public class heapSort {
public static void main(String[] args){
int[] arr = {1,3,5,7,4,6,3,6};
heapSort(arr);
for(int x:arr){
System.out.print(x+" ");
}
System.out.println();
}
public static void heapSort(int[] arr){
int n = arr.length;
for(int i=0;i<arr.length;i++){
heapInsert(arr,i);
}
int size = n;
while (size>1){
swap(arr,--size,0);
heapify(arr,0,size);
}
}
public static void heapInsert(int[]arr,int i){
while(arr[i]>arr[(i-1)/2]){
swap(arr,i,(i-1)/2);
i = (i-1)/2;
}
}
public static void heapify(int[]arr,int i,int size){
int l = i*2+1;
while(l<size){
int best = l+1<size&&arr[l+1]>arr[l]?l+1:l;
best = arr[best]>arr[i]?best:i;
if(best==i)break;
swap(arr,best,i);
i = best;
l = i*2+1;
}
}
public static void swap(int[] arr,int x,int y){
int temp = arr[x];
arr[x] = arr[y];
arr[y] = temp;
}
}