思路:
始终维持一个K个元素的最小堆,对输入的前K个元素,先构成一个K个元素的最小堆,然后对后面输入的每个元素,先和堆顶a[0]比较,若小于等于a[0],则不做处理,否则,将当前输入的元素赋值给a[0],然后将其下浮到合适的位置。
import java.util.ArrayList;
import java.util.Arrays;
public class zuidadui {
public static void main(String[] args){
int aim[] = {1, 2, 5, 10, 3, 7, 11, 15, 17, 20, 9, 15, 8, 16};
int len = aim.length;
int haipa[] = new int[len],q=0;
for(int p:aim){
haipa[q++] = (-1)*p;
}
int K = 5;
Arrays.sort(haipa);
Show(haipa);
build_min_dui(aim,K); //通过上浮的方法构建K个元素的最小堆
Show(aim);
for(int j = K;j<len;j++) { //对从 K+1 到元素末尾 ,插入最小堆
//若要插入的元素比堆顶元素小或相等,则不处理,否则将其付给堆顶元素,并将其下沉到合适位置。
if(aim[j] > aim[0]){
down(aim, K, j);
}
}
Show(aim);
}
public static void build_min_dui(int a[],int K){
for(int i = 1;i< K;i++){
up_floor(a, i);
}
}
public static void down(int a[],int K,int cur) {
a[0] = a[cur];
cur = 0;
while(cur < K){
int child = 2*cur + 1;
if(child >= K)break;
else{
if(child < K -1 && a[child] >a[child +1]){
child++;
}
if(a[cur]>a[child]){
int tempt = a[child];
a[child] = a[cur];
a[cur] = tempt;
cur = child;
}else
break;
}
}
}
public static void up_floor(int a[],int flag){
int tt;
if(flag > 0){
int par = (flag - 1)/2;
if(a[par] > a[flag]) {
tt = a[flag];
a[flag] = a[par];
a[par] = tt;
up_floor(a, par);
}
}
}
public static void Show(int a[]){
for(int i : a){
System.out.print(i + " ");
}
System.out.println();
}
}