求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"); } }