前K个数.

     逆序排列前K个数,因为数据量太大,不能全部存储再内存中,只能一个一个地从磁盘或者网络上读取数据,设计一个高效地算法来解决这个问题。

不限制用户输入数据的个数,用户每输入一个数据就回车,使得程序可以立即获取这个数据,用户输入-1代表终止。

然后用户输入K,代表要求得到的TOPK

public class Xiaodingdui {
	static int index=0;
    static int[] heap;
    static int k;

    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        k=sc.nextInt();
        heap=new int[k];
        int x=sc.nextInt();
        while(x!=-1){
            deal(x);
            x=sc.nextInt();
        }
        System.out.println(Arrays.toString(heap));
    }

    private static void deal(int x) {
        if(index<k){
            heap[index++]=x;
            //当topK存满则进行堆化(小顶堆)
            if(index==k){
                buildMinHeap(heap,heap.length);
            }
        }else {
            if(heap[0]<x){
                heap[0]=x;
                minHeadAdjust(heap,0,heap.length);
            }
        }

    }

    private static void buildMinHeap(int[] heap, int length) {
        //减一因为0号位也存有元素
        for (int i = length/2-1; i >0 ; i--) {
            minHeadAdjust(heap,i,heap.length);
        }
    }

    private static void minHeadAdjust(int[] heap, int i, int length) {
        //找到左右孩子
        int left=i*2+1;
        int right=i*2+2;

        //该节点为叶子节点
        if(left>=length){
            return;
        }
		//寻找孩子节点中最小的一个
        int min=left;
        if(right<length&&heap[right]<heap[left]){
            min=right;
        }

        if(heap[i]<=heap[min]){
            return;
        }else {
            int temp=heap[i];
            heap[i]=heap[min];
            heap[min]=temp;
        }
        minHeadAdjust(heap,min,heap.length);
    }


}

结果如下:

 

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值