求TOP K数据问题。
一般的思路是,求最小值,用最大堆,求最大值,用最小堆。
拿球最大值来看。用最小堆,先对一个数组的前K个数组进行一个建堆操作,建立最小堆。然后对剩余数组进行选择,如果比堆中最小值的数据大,则替换最小值,然后更新堆,如果比最小值还小,则丢弃。
下面给出代码。我先贴上最小堆的代码。
package com.tools;
public class MinHeap {
public int[] num;
public MinHeap(int[] num){
this.num = num;
build();
}
//交换数据
private void swap(int i , int j){
int temp;
temp = i;
i = j;
j = temp;
}
//初始化构造二叉堆
private void build(){
for(int i = 0 ; i <= num.length/2-1; i++){
Heap(i);
}
}
//对堆进行整理
private void Heap(int index){
int small = index;
int left,right;
left = (index+1)*2-1;
right = (index+1)*2;
if(left<num.length&&num[left]<num[index])
small = left;
if(right<num.length&&num[right]<num[small])
small = right;
if(small == index)
return;
int temp;
temp = num[small];
num[small] = num[index];
num[index] = temp;
Heap(small);
}
public int GetRoot(){
return num[0];
}
public void SetHeadValue(int value){
num[0] = value;
Heap(0);
}
}
下面给出实验代码。
package com.algorithm05;
import java.util.Scanner;
import com.tools.MinHeap;
public class Algorithm40 {
public static void main(String[] args) {
int[] num = new int[]{5,2,1,4,8,12,3,100,2000,30,50};
Scanner scanner = new Scanner(System.in);
int k;
k = scanner.nextInt();
int[] topK = new int[k];
//首先将数组中前k个数放入topk数组中。
for(int i = 0 ; i < k ; i++){
topK[i] = num[i];
}
//将topk数组转换为最小堆
MinHeap minHeap = new MinHeap(topK);
//前k个数据进入topk数组中,之后对数组中剩余数组进行最小堆的匹配
for(int j = k ; j < num.length; j++){
//如果数组中的值比topk最小的值还要小,则对其进行更换。并更新topk的数组的结构
if(num[j]>minHeap.num[0])
{
minHeap.num[0] = num[j];
minHeap.SetHeadValue(num[j]);
}
}
System.err.println("pause");
}
}