问题描述:
取给定List中的前TopK个最大的元素并输出。
关键点:
1. topK个最大的元素
2. 我们并不需要顺序,因此一切涉及到sort的工作都是不必要的。
3. 要且只要topK个元素,no more needed!!
因此,我们虽然用堆,但并不需要将整个list都建成堆,只需要维护一个K个元素的堆即可。
其次,我们的堆并不用来排序,这点很重要!!!
具体步骤如下:——求最大的TopK个元素
1. 建一个K个元素的空堆 HP,即一个K个元素的数组
2. 遍历原List,将元素依次压入HP中,在压入过程中:
2.1 如果压入的个数还不到K个,则直接压入,
2.2 如果压入之后的个数达到K个,则将该K个元素维护成一个堆结构
2.3 在压入每个元素之前,如果HP中已经有K个元素,则将新元素与HP的第一个元素比较
2.3.1 如果新元素大于HP的第一个元素,则将新元素放在HP的第一个位置,并调整HP堆。
2.3.2 如果新元素小于HP的第一个元素,则continue 到 2.
遍历完后HP中的K个元素即为List中的前TopK大的元素。
package sortNumbers;
public class SortNumbers {
/*
*
*/
public static void adjustMinHeap(int[] a,int pos,int len){
int temp;
int child;
for(temp = a[pos];2*pos+1<=len;pos=child){
child = 2*pos + 1;
if(child < len&&a[child]>a[child+1]){
child++;
}
if(a[child]<temp){
a[pos] = a[child];
}
else
break;
}
a[pos] = temp;
}
public static void myMinHeapSort(int[] array){
int i;
int len = array.length;
int k = 3;// 查找最大的3个数
for(i = k/2-1;i >= 0;i--){
adjustMinHeap(array,i,k - 1);
}
int tmp = 0;
for(int j = k;j < len;j++ ){
if(array[j] > array[0]){
tmp = array[j];
array[j] = array[0];
array[0] = tmp;
adjustMinHeap(array,0,k -1);
}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int i = 0;
int a[] = {15,5,13,4,9,11,10,8,7,6,0,12,1,3,2,14};
int len = a.length;
myMinHeapSort(a);
for(i = 0;i < len;i++){
System.out.print(a[i]+" ");
}
}
}