求一亿个数字里面最小的10个数字

package com.yuzhiyun;

import java.util.Arrays;

/**
 * 求一亿个数里面最小的10个数
 * 首先建立节点个数为10的最大堆,然后考虑每一个新的值,让他和堆顶比较,比堆顶大的元素直接抛弃,如果比堆顶小的数字,让他替换堆顶,然后调整堆。
 */
public class MaxTenNumber {
    public static void main(String[] args) {
        /**第一个元素0不参与,只是用于占位置,这样的话,只要array[k]>array[2k] && array[k]>array[2k+1]那就是最大堆了,
         * 此外,这里暂时用20个数代替1亿个
         */
        int[] array={0,1,2,3,4,7,8,9,10,11,12,13,14,15,16,17,18,19,20,6,5};
        //建立建立节点个数为10的最大堆
        for(int i=10/2;i>=1;i--){
            adjustHeap(array, i, 10);
        }
        //System.out.println(Arrays.toString(array));
        for(int i=11;i<array.length;i++){
            //如果这个元素小于堆顶,和堆顶交换,然后重新调整堆
            if(array[i]<array[1]){
                swap(array, i, 1);
                adjustHeap(array, 1, 10);
            }

        }
        System.out.println(Arrays.toString(array));
        System.out.println("最小的10个数字为:");
        for(int i=1;i<=10;i++){
            System.out.print(array[i]+" ");
        }
    }

    /**
     * 交换
     * @param array
     * @param i
     * @param j
     */
    private static void swap(int[] array, int i, int j) {
        int tem=array[i];
        array[i]=array[j];
        array[j]=tem;
    }

    /**
     * 在以array[head]为根的左右子树是最大堆的前提下把以array[head]为根的树调整为最大堆
     * @param array
     * @param head
     * @param tail
     */
    static void adjustHeap(int[] array,int head,int tail){
        int root=array[head];
        int i=2*head;
        while(i<=tail){
            int max=array[i];
            if(i+1<=tail)
                if(array[i+1]>array[i]){
                    max=array[i+1];
                    i++;
                }
            if(root>max)
                //别手抖写成了return;
                break;
            else{
                array[i/2]=array[i];        
            }
            i*=2;
        }
        array[i/2]=root;
    }
}
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值