常见的堆排序:先构建大顶堆,每次将大顶与最后一个数替换,重新构建大顶堆。
public class Test {
public static void main(String[] args) {
int[] arr={7,2,4,9,3,0,15,11,67,24,99,18,55};
new Test().heapSort(arr);
for(int a:arr){
System.out.println(a);
}
}
public void heapSort(int[] arr){
int lenth=arr.length;
/**
*@TODO:构建大根堆 注意思考为什么是length/2-1,可以考虑节点数为3的时候模拟公式。
*@return: void
*/
for(int i=lenth/2-1;i>=0;i--){
adjustHead(arr,i,lenth);
}
/**
*@TODO:每次将最后一个数和第一个数替换,然后将剩下的数组继续;排成最大堆
*@return: void
*/
for(int j=lenth-1;j>=0;j--){
swap(arr,0,j);
adjustHead(arr,0,j);
}
}
/**
*核心代码
*/
private void adjustHead(int[] arr,int i,int length){
int temp=arr[i];
int child;
for(child=2*i+1;child<length;child=2*child+1){
if(child+1<length && arr[child]<arr[child+1]){
child++;
}
if(arr[child]>temp){
swap(arr,i,child);
i=child;//思考为什么要替换i
}
else {
break;//思考为什么要用break而不是continue
}
}
}
private void swap(int[] arr, int i, int j) {
int temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
}
变种题: 查找数组中最大的K个数。
-
如果要找最大的数,那么就是小顶堆,如果要找最小的数,那就是大顶堆。逻辑关系要理清楚。
-
寻找最大的K个数,意味着你需要维护一个根节点数目为K的堆。在你构建这么一个堆之后,就要开始进行比较和重构。之所以要构建小顶堆,是为了保证每次比较工作都是最简洁高效的。第K+1个数如果小于堆顶,必然小于堆中其他任意元素,如果大于堆顶,交换元素之后只需要重构最小堆。最终维护的最小堆就是我们所需要的最大的K个数。
import java.util.ArrayList; public class Test10 { public static void main(String[] args) { int[] arr={1,4,7,3,9,7,8,5,3,6,0}; System.out.print(new Test10().sortHeap(arr,3)); } public ArrayList<Integer> sortHeap(int[] arr, int k){ ArrayList<Integer> list=new ArrayList<>(); int length=arr.length; /** *@TODO:构建总数为k的小顶堆 *@return: */ for(int i=k/2-1;i>=0;i--){ adjustHead(arr,i,k); } for(int j=k;j<length;j++){ if(arr[j]>arr[0]){ swap(arr,j,0); adjustHead(arr,0,k); } } for(int i=0;i<k;i++){ list.add(arr[i]); } return list; } /** * 核心 * */ private void adjustHead(int[] arr,int i,int length){ int temp=arr[i]; int child; for(child=2*i+1;child<length;child=2*child+1){ if(child+1<length && arr[child+1]<arr[child]){ child=child+1; } if(arr[child]<temp){ swap(arr,child,i); i=child; } else { break; } } } private void swap(int[] arr, int child, int i) { int temp=arr[i]; arr[i]=arr[child]; arr[child]=temp; } }