最小的K个数,堆排序——剑指offor Java程序

xiaoxiao2021-02-28  121

    对于海量数据中,数量量大于内存可接受的数据,需要选择出最小的k个数,内存无法对所有的数据进行排序,因此可采用一个大小为k的堆容器b[],进行辅助排序。对于原始数据数组a[],大小为n,n>>k。

    初始时将n个元素中的前k个元素存储在堆容器b[]数组中,并对其进行堆排序,建立大顶堆(所有父节点的元素大于子节点)。堆排序是从第一个非叶子节点开始进行调整,此节点与其子节点进行比较,若子节点大于父节点,则将父节点与子节点进行交换,这一交换可能使子节点的子树不满足大顶堆的特点,因此需要递归重新调整子树。

    然后对n个元素剩下的所有元素进行操作,若元素大于大顶堆的堆顶元素,则对其不进行任何操作。反之,该元素替换堆顶元素,并进行堆调整。

    最后堆容器b[]中的元素便是最小的k个元素。

    时间复杂度O(nlogk),优点:不需要改变输入数组,适合处理海量数组。

public class GetLeastNumbers { public static void main(String[] args) { // TODO Auto-generated method stub int a[]={4,5,1,6,2,7,3,8,0}; int b[]=get_min_k(a,4); for(int i=0;i<b.length;i++) { System.out.println(b[i]); } } public static int[] get_min_k(int a[],int k) { int b[]=new int[k]; if(a.length<=k) return a; for(int i=0;i<k;i++) b[i]=a[i]; for(int i=(k-1)/2;i>=0;i--) adjustHeap(b,i); for(int i=k;i<a.length;i++) if(a[i]<b[0]) { b[0]=a[i]; adjustHeap(b,0); } return b; } private static void adjustHeap(int[] b, int i) { // TODO Auto-generated method stub int index=i; int left=2*i+1; int right=2*i+2; if(left<b.length&&b[index]<b[left]) index=left; if(right<b.length&&b[index]<b[right]) index=right; if(index!=i) { int temp=b[i]; b[i]=b[index]; b[index]=temp; adjustHeap( b, index); } } }

转载请注明原文地址: https://www.6miu.com/read-36813.html

最新回复(0)