堆排序TopK

package test;

import java.util.Random;

public class TSort {

    public static void main(String[] args) {
        TSort tsort = new TSort();
        tsort.test();
    }

    public void test() {
        TopHundredHeap.test(null);
    }

    public void testt(String a, double[] d, String[] t, String... c) {
        Math.random();
    }
}

class TopHundredHeap {

    public static void test(String[] args) {
        // the size of the array
        int number = 100000000;
        // the top k values
        int k = 100;
        // the range of the values in the array
        int range = 1000000001;

        // input for minHeap based method
        int[] array = new int[number];

        Random random = new Random();
        for (int i = 0; i < number; i++) {
            array[i] = random.nextInt(range);
        }

        TopHundredHeap thh = new TopHundredHeap();

        long t1, t2;
        // start time
        t1 = System.currentTimeMillis();
        int[] top = thh.topHundred(array, k);

        // end time
        t2 = System.currentTimeMillis();
        System.out.println("The total execution time of " + "quicksort based method is " + (t2 - t1) + " millisecond!");

        // print out the top k largest values in the top array
        System.out.println("The top " + k + "largest values are:");
        for (int i = 0; i < k; i++) {
            System.out.println(top[i]);
        }
    }

    public int[] topHundred(int[] array, int k) {
        // the heap with size k
        int[] top = new int[k];

        for (int i = 0; i < k; i++) {
            top[i] = array[i];
        }

        buildMinHeap(top);

        for (int i = k; i < array.length; i++) {
            if (top[0] < array[i]) {
                top[0] = array[i];
                minHeapify(top, 0, top.length);
            }
        }

        return top;
    }

    // create a min heap
    public void buildMinHeap(int[] array) {
        int heapSize = array.length;
        for (int i = array.length / 2 - 1; i >= 0; i--) {
            minHeapify(array, i, heapSize);
        }
    }

    /// MinHeapify is to build the min heap from the ‘position‘
    public void minHeapify(int[] array, int position, int heapSize) {
        int left = left(position);
        int right = right(position);
        int maxPosition = position;

        if (left < heapSize && array[left] < array[position]) {
            maxPosition = left;
        }

        if (right < heapSize && array[right] < array[maxPosition]) {
            maxPosition = right;
        }

        if (position != maxPosition) {
            swap(array, position, maxPosition);
            minHeapify(array, maxPosition, heapSize);
        }
    }

    public void swap(int[] array, int i, int j) {
        int temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }

    /// return the left child position
    public int left(int i) {
        return 2 * i + 1;
    }

    /// return the right child position
    public int right(int i) {
        return 2 * i + 2;
    }
}
时间: 2024-10-26 04:05:05

堆排序TopK的相关文章

minheap+hashmap组合解决动态topK问题(附堆排序完整实现)

TopK的解决方法一般有两种:堆排序和partition.前者用优先队列实现,时间复杂度为O(NlogK)(N为元素总数量),后者可以直接调用C++ STL中的nth_element函数,时间复杂度O(N).如果想获取动态更新数据的topK就不那么容易了,比如实时更新最常访问的top10的网址,显然除了维护一个size为10的最小堆以外还需要一个哈希表实时记录每一个网址的访问次数,并决定是否动态加入到最大堆中,同时可能删除堆中的元素.那么如何获得该网址在堆中的位置呢?需要另一个hashmap记录

关于堆排序和topK算法的PHP实现

问题描述 topK算法,简而言之,就是求n个数据里的前m大个数据,一般而言,m<<n,也就是说,n可能有几千万,而m只是10或者20这样的两位数. 思路 最简单的思路,当然是使用要先对这n个数据进行排序,因为只有排序以后,才能按照顺序来找出排在前面的,或者排在后面的数据. 假如说我们用快拍,那么时间复杂度是O(nlogn),但是仔细看题目,会发现实际上不要要将所有的数据就进行排序,因为我们找的是前m个数据,所以对所有数据排序实际上有些浪费了.所以可以想到,只维护一个大小为m的数组,然后扫一遍原

堆排序应用之topK问题

题目:求海量数据(正整数)按逆序排列的前k个数(topK),因为数据量太大,不能全部存储在内存中,只能一个一个地从磁盘或者网络上读取数据,请设计一个高效的算法来解决这个问题. 第一行用户输入K,代表要求得topK  随后的N(不限制)行,每一行是一个整数代表用户输入的数据 直到用户输入-1代表输入终止 请输出topK,空格分割. 思路:先开辟一个K大小的数组arr,然后读取K个数据存储到数组arr,读到K+1的时候,如果arr[K+1]小于arr中最小的值,那么就丢掉不管,如果arr[K+1]大

算法 排序NB二人组 堆排序 归并排序

参考博客:基于python的七种经典排序算法     常用排序算法总结(一) 序前传 - 树与二叉树 树是一种很常见的非线性的数据结构,称为树形结构,简称树.所谓数据结构就是一组数据的集合连同它们的储存关系和对它们的操作方法.树形结构就像自然界的一颗树的构造一样,有一个根和若干个树枝和树叶.根或主干是第一层的,从主干长出的分枝是第二层的,一层一层直到最后,末端的没有分支的结点叫做叶子,所以树形结构是一个层次结构.在<数据结构>中,则用人类的血统关系来命名,一个结点的分枝叫做该结点的"

排序算法Java版,以及各自的复杂度,以及由堆排序产生的top K问题

常用的排序算法包括: 冒泡排序:每次在无序队列里将相邻两个数依次进行比较,将小数调换到前面, 逐次比较,直至将最大的数移到最后.最将剩下的N-1个数继续比较,将次大数移至倒数第二.依此规律,直至比较结束.时间复杂度:O(n^2) 选择排序:每次在无序队列中"选择"出最大值,放到有序队列的最后,并从无序队列中去除该值(具体实现略有区别).时间复杂度:O(n^2) 直接插入排序:始终定义第一个元素为有序的,将元素逐个插入到有序排列之中,其特点是要不断的 移动数据,空出一个适当的位置,把待插

简单的topK问题

/************************************************************************/ /* 求一组数据中的top(K)问题,这是一个经典的top(K)问题. 分析: 方法一:如果数据量不大,那么最常用的方法就是排序从大大小,然后找出前k个数据. 比较高效率的排序算法,如快排,堆排序等,总体时间复杂度为 O(N*log2(N))+O(K)=O(N*log2(N)) 或是直接用部分排序算法,如选择排序,直接找出前K个元素,时间复杂度为O

Java 小根堆排序

Counter类:计数器 IntPk中包含主键 public class Counter extends IntPK{     private int count;     public int getCount() {         return count;     }     public void setCount(int count) {         this.count = count;     } } MinHeap类:最小堆排序类 package com.ryx.incan

排序中topK那点事(转)

问题描述:有 N (N>1000000)个数,求出其中的前K个最小的数(又被称作topK问题). 这类问题似乎是备受面试官的青睐,相信面试过互联网公司的同学都会遇到这来问题.下面由浅入深,分析一下这类问题. 思路1:最基本的思路,将N个数进行完全排序,从中选出排在前K的元素即为所求.有了这个思路,我们可以选择相应的排序算法进行处理,目前来看快速排序,堆排序和归并排序都能达到O(NlogN)的时间复杂度.当然,这样的答案也是无缘offer的. 思路2:可以采用数据池的思想,选择其中前K个数作为数据

堆的应用(1000个数据中找最大的前K个元素,堆排序)

(1)从1000个数据中找到k个最大数据 首先看到这个题时,可能会想到先将这1000个数据进行降序排序,即取出的前k个元素最大.时间复杂度为O(N^2),使得程序效率低. 如何解决这个问题呢?我们的堆就派上用场喽! 解题思路: 可先创建一个数组topK[k],将100w中的前k个数据放入数组topK中,将topK中的数据建小堆,则可保证堆的第一个元素是最小的,将第k个元素与堆中第一个元素比较,若大于,则交换.对堆进行重新建小堆,取第k+1个元素与堆中第一个元素比较,以此类推,直至100w-k个元