/**
* 寻找最大的K个数
* @author Administrator
* 利用最小堆来存储前K个数,堆顶为最小数,将X于堆顶元素比较,若大于则将X插入堆
* 然后更新堆
*/
public class FindMaxKNum {
public int[] find(int[] heap,int[] arr){
for(int i=heap.length;i<arr.length;i++){
refreshHeap(arr[i], heap, heap.length);
}
return heap;
}
/**
* 更新堆操作
*/
private void refreshHeap(int x,int[] heap,int k){
//如果x>heap[0]则更新堆
if(x>heap[0]){
heap[0] = x;
//节点p
int p=0;
while(p<k){
//节点左子数
int q = 2*p+1;
//如果q大于总数k则推出
if(q>k)
break;
//如果右节点q+1>左节点q则交换节点指针,保证q始终指向大的节点;q<k-1表示最后2个元素交换位置与否不影响结果
if((q<k-1)&&(heap[q+1]<heap[q]))
q = q + 1;
//如果p节点大于q节点表明子节点大于当前节点,则更新两个节点的值
if(heap[q]<heap[p]){
int t = heap[p];
heap[p] = heap[q];
heap[q] = t;
p = q;
}else{
break;
}
}
}
}
}
@Test
public void findMaxKNum(){
FindMaxKNum fmk= new FindMaxKNum();
int[] arr = {9,3,5,1,6,4,7,0,2,8,45,15,99,12,14,3,4,2,44,23,4};
int[] heap = {1,3,5,9};
int[] ar = fmk.find(heap, arr);
for(int i=0;i<ar.length;i++){
System.out.println(ar[i]);
}
}