Java堆排序,取得前TopN个数

import java.util.Random;
/**
 * Created with IntelliJ IDEA.
 * User: pengfei.hpf
 * Date: 14-4-29
 * Time: 上午11:45
 * To change this template use File | Settings | File Templates.
 */
public class HeapSortUtil {

    /**
     * 用堆排序方法  找出前N个最大的数
     * @originalArray 原始数据数组
     * @topN 需要取得的N个最大数
     * @return  包含topN个最大数的数组
     */
    public int[] getTopArray(int[] originalArray,int topN){
        int len = originalArray.length ;
        if(len <= topN){
            return  originalArray;
        }
        int[] array = new int [topN];
        initHeap(originalArray);
        int temp;
        for(int i=0;i<array.length;i++){
            array[i]= originalArray[0];
            temp=originalArray[originalArray.length-i-1];
            originalArray[originalArray.length-i-1]=originalArray[0];
            originalArray[0]=temp;
            buildHeap(0,originalArray.length-i-1,originalArray);
        }

        return array;
    }
    /**
     * 创建初始无序堆
     */
    private void initHeap(int[] orignalArr){
        for(int i=orignalArr.length-1;i>=0;i--){
            buildHeap(i,orignalArr.length,orignalArr);
        }
    }
    /**
     * 调整堆
     * @param location 起始位置
     * @param unSortLength 无序堆的长度
     */
    private void buildHeap(int location,int unSortLength,int[] arr){
        int temp;
        int tempLoc;
        //判断该父节点是否有左右孩子
        if((tempLoc = (location+1)*2)<unSortLength){
            if(arr[tempLoc]>arr[tempLoc-1]){//如果右节点大于左节点
                if(arr[tempLoc]>arr[location]){//如果右节点大于父节点  就双方交换值
                    temp = arr[location];
                    arr[location] = arr[tempLoc];
                    arr[tempLoc] = temp;
                    buildHeap(tempLoc,unSortLength,arr);//递归
                }
            }else{//如果左节点大于右节点
                if(arr[tempLoc-1]>arr[location]){//如果左节点大于父节点
                    temp = arr[location];
                    arr[location] = arr[tempLoc-1];
                    arr[tempLoc-1] = temp;
                    buildHeap(tempLoc-1,unSortLength,arr);//递归
                }
            }
        }else if((tempLoc =((location+1)*2-1))<unSortLength){//如果该父节点有左节点
            if(arr[tempLoc]>arr[location]){//如果右节点大于父节点
                temp = arr[location];
                arr[location] = arr[tempLoc];
                arr[tempLoc] = temp;
                buildHeap(tempLoc,unSortLength,arr);//递归
            }
        }
    }

    public static void main(String[] args) {
        int[] arr =new int[100000];
        Random ran = new Random();
        for (int i = 0; i < arr.length; i++) {
            arr[i] = ran.nextInt(100000);
        }
        HeapSortUtil h  = new HeapSortUtil();
        long start =  System.currentTimeMillis();
        int topArr[] = h.getTopArray(arr, 20);
        //打印出排序后的数组
        for(int i=0;i<topArr.length;i++){
            System.out.println(topArr[i]);
        }

        long end = System.currentTimeMillis()-start;
        System.out.println("Total time:" + end + "ms");
    }
}

Java堆排序,取得前TopN个数,码迷,mamicode.com

时间: 2024-08-19 14:34:02

Java堆排序,取得前TopN个数的相关文章

100万个数中找出最大的前K个数

拿到这个题目我想到了很多方法,但是在我想到的方法中,要把在100万个数中找到前k个数,都不适用.最后通过我的不断研究,我想到了我认为最简单的方法,就是利用堆来做这道题目. 下面我分析一下我用堆排序的思路: 1.我先建一个大小为k的堆. 2.把100万中前k个数放到这个堆中. 3.把这个堆调成小堆. 4.把100万个从k到100万之间的数字拿出来和堆的根结点作比较. 5.如果根结点小于这之间的某一个数,就把这个数拿给根结点,然后继续调成小堆.否则继续找 6.直到找完这100万个数,堆中放的就是最大

【海量数据处理】N个数中找出最大的前K个数

N个数中找出最大的前K个数,需要用小堆实现. 分析:由于小堆的堆顶存放堆中最小的数据,可以通过与堆顶数据进行比较,将大数据存放在堆中,注意在每次改变堆顶数据后,进行调堆,使堆顶一直存放整个堆中最小元素. void AdjustDown(int *a, size_t root, size_t size)//下调 {//小堆 size_t parent = root; size_t child = parent * 2 + 1; while (child < size) { if (child + 

Java 9的前9大改进和功能,程序员可以先了解下

Java 9的前9大改进和功能,程序员不妨先了解2017-08-04 10:13程序设计/操作系统/客户端Java 9即将推出.你准备好新版本将带来的新功能吗?在本文中,笔者对Java重要的生态系统的改变,包括新的模块系统,语言和语法的变化等,进行综合介绍. Java 9随着发布的日期临近,程序员和开发者对其带来的新功能的兴趣逐渐升高.新Java版本的发布日期是2017年9月21日.还有不到两个月的时间!Java 9有很多变化,下面我将列出将其添加到新的Java 9中的9个重要改进. 1.新模块

java几秒前,几分钟前,几小时前,几天前,几月前,几年前的实现

原文:java几秒前,几分钟前,几小时前,几天前,几月前,几年前的实现 源代码下载地址:http://www.zuidaima.com/share/1562038902000640.htm 以前有牛人分享的代码: java实现几分钟前,几小时前,几天前的代码 有点复杂,所以在stackoverflow上找了一个简单的,改写了下符合需求,给大家分享下. package com.date; import java.text.ParseException; import java.text.Simpl

递归算法输出数列的前N个数

数列1,1,1,3,5,9,17,31,57,105--N大于3时,第N个数为前三个数之和. 1 for (int i = 0; i < 10; i++) 2 { 3 listint.Add(1); 4 } 5 test3(10); 6 test3(); 1 List<int> listint = new List<int>(); 2 int test3(int n) 3 { 4 int result = 1; 5 if (n > 3) 6 { 7 result = t

【c语言】求斐波那契数列的前40个数。特点,第1,2个数为1,从第三个数开始,该数是前面两个数之和

// 求斐波那契数列的前40个数.特点,第1,2个数为1,从第三个数开始,该数是前面两个数之和 #include <stdio.h> int main() { int a = 1; int b = 1; int c,i; printf("%d\t%d\t",a,b); for(i = 3; i <= 40; i++) { c = a + b; printf("%d\t",c); a = b; b = c; } printf("\n&quo

数论线性筛总结 (素数筛,欧拉函数筛,莫比乌斯函数筛,前n个数的约数个数筛)

线性筛 线性筛在数论中起着至关重要的作用,可以大大降低求解一些问题的时间复杂度,使用线性筛有个前提(除了素数筛)所求函数必须是数论上定义的积性函数,即对于正整数n的一个算术函数 f(n),若f(1)=1,且当a,b互质时f(ab)=f(a)f(b),在数论上就称它为积性函数,若a,b不互质也满足的话则称作完全积性函数,下面说明每个筛子是怎么筛的. 最基础的是素数筛,其它三个筛都是以素数筛为前提 素数筛 void get_prime() { int pnum = 0; for(int i = 2;

Java NIO 的前生今世 之四 NIO Selector 详解

Selector Selector 允许一个单一的线程来操作多个 Channel. 如果我们的应用程序中使用了多个 Channel, 那么使用 Selector 很方便的实现这样的目的, 但是因为在一个线程中使用了多个 Channel, 因此也会造成了每个 Channel 传输效率的降低.使用 Selector 的图解如下: 为了使用 Selector, 我们首先需要将 Channel 注册到 Selector 中, 随后调用 Selector 的 select()方法, 这个方法会阻塞, 直到

键盘录入一个文件夹路径,统计该文件夹(包含子文件夹)中每种类型的文件及个数,注意:用文件类型(后缀名,不包含.(点),如:&quot;java&quot;,&quot;txt&quot;)作为key, 用个数作为value,放入到map集合中,遍历map集合

package cn.it.zuoye5; import java.io.File;import java.util.HashMap;import java.util.Iterator;import java.util.Map;import java.util.Scanner;import java.util.Set; /** 键盘录入一个文件夹路径,统计该文件夹(包含子文件夹)中每种类型的文件及个数,注意:用文件类型(后缀名,不包含.(点),如:"java","txt&qu