package com.wentora.exercise; /** * 求数组中最大的k个数 * 思想:首先取出数组中前k个数,建一小根堆,然后依次取出数组中剩余的n-k个数与堆首元素进行比较 * 如果小于堆首,则不可能是所求元素,如果大于,则与堆首交换,再调整堆即可 * @author wentora */ import java.util.Arrays; import java.util.Random; import java.util.Scanner; public class MaxK { int[] a; int k; int[] b; MaxK(int[] a, int k) { this.a = a; this.k = k; b = new int[k]; for(int i = 0; i < k; i++) b[i] = a[i]; } //建堆 void createHeap() { for(int i = (k - 2) / 2; i >= 0; i--) heapAdjust(i); } //堆调整 void heapAdjust(int i) { int j = 0; int temp = b[i]; for(j = 2 * i + 1; j < k ; j = 2 * j) { if(j + 1 < k && b[j + 1] < b[j] ) j++; if(temp < b[j]) break; b[i] = b[j]; i = j; } b[i] = temp; } //将数组a中后n-k个元素分别与堆首元素进行比较,得到最大的k个数 void getK() { for(int i = k; i < a.length; i++) { if(a[i] <= b[0]) continue; else { b[0] = a[i]; heapAdjust(0); } } } void outputK() { System.out.print("the biggest k numbers are : " + Arrays.toString(b)); } /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub Random rand = new Random(); Scanner scan = new Scanner(System.in); int len; System.out.print("please input array size : "); len = scan.nextInt(); int k; System.out.print("please input k : "); k = scan.nextInt(); int[] a = new int[len]; for(int i = 0; i < len; i++) a[i] = rand.nextInt(len); System.out.println("array a is : " + Arrays.toString(a)); MaxK mk = new MaxK(a, k); mk.createHeap(); mk.getK(); mk.outputK(); } }