创建大小为k的堆,当容器满时:
1、在k个数中找到最大数,
2、删除容器最大数,然后调整堆;
3、插入一个新数,调整堆;
适合海量数据,时间复杂度O(nlgk)
import java.util.Arrays;
public class GetLeastKNumbers {
public int getParent(int i) {
return (i - 1) >> 1;
}
public int getLeftChild(int i) {
return (i << 1) + 1;
}
public int getRightChild(int i) {
return (i << 1) + 2;
}
public void buildMaxHeap(int[] data) {
int length = data.length;
int startIndex = length / 2 - 1;
for (int i = startIndex; i >= 0; i--)
maxHeap(data, length, i);
}
public void maxHeap(int[] data, int heapSize, int index) {
int left = getLeftChild(index);
int right = getRightChild(index);
int largest = index;
if (left < heapSize && data[left] > data[index])
largest = left;
if (right < heapSize && data[right] > data[largest])
largest = right;
if (largest != index) {
int tmp = data[index];
data[index] = data[largest];
data[largest] = tmp;
maxHeap(data, heapSize, largest);
}
}
public void heapSort(int[] data) {
for (int i = data.length - 1; i >= 0; i--) {
int tmp = data[0];
data[0] = data[i];
data[i] = tmp;
maxHeap(data, i, 0);
}
}
public int[] getLastNumbers(int[] a, int k) {
int[] kNumbers = new int[k];
if (a == null || k < 1 || a.length < k)
return null;
for (int i = 0; i < k; i++)
kNumbers[i] = a[i];
buildMaxHeap(kNumbers);
for(int i=k;i<a.length-1;i++)
{
if(kNumbers[0]>a[i])
{
kNumbers[0] = kNumbers[k-1];
maxHeap(kNumbers, k-1, 0);
kNumbers[k-1]=a[i];
int parent;
for(int j=k-1;j>=0;j=parent)
{
parent=getParent(j);
if(parent>=0&&kNumbers[j]>kNumbers[parent])
{
int tmp = kNumbers[j];
kNumbers[j] = kNumbers[parent];
kNumbers[parent] = tmp;
}
else
break;
}
}
}
return kNumbers;
}
public static void main(String[] argv)
{
int a[]={1,23,2,-1,5,12,6,2};
int[] k=new GetLeastKNumbers().getLastNumbers(a, 2);
System.out.println(Arrays.toString(k));
}
}