小顶堆:

我们利用的特性:每个节点都比左右孩子小

图示:

取数组前n个数,构成小顶堆

然后从数组里面获取数据,如果比堆顶小,直接抛弃,如果比堆顶大,就替换堆顶,并调整堆,使堆始终满足小顶堆的特性

93比18大,替换18

调整堆

然后依次处理下一个数44

对数组内的数调整完成后,前n个大的数 就在小顶堆里面了

平均时间复杂度为Ο(nlogn)

代码实现:

import java.util.Arrays;public class TopN {/*** 父节点*/private int parent(int n) {return (n - 1) / 2;}/*** 左孩子*/private int left(int n) {return 2 * n + 1;}/*** 右孩子*/private int right(int n) {return 2 * n + 2;}/*** 构建堆* * @param n*            构建包含n个节点的堆* @param data*            构建堆的数据*/public void buildHeap(int n, int[] data) {for (int i = 1; i < n; i++) {int t = i;// 调整堆while (t != 0 && data[parent(t)] > data[t]) {int temp = data[t];data[t] = data[parent(t)];data[parent(t)] = temp;t = parent(t);}}}/*** 调整堆* * @param i*            被调整的数在数据中的下标* @param n*            从第n个数开始 不在之前构建的堆里面* @param data*            需要被调整的数据*/public void adjust(int i, int n, int[] data) {// 被调整的数小于堆顶 不做任何操作if (data[i] <= data[0])return;// 被调整的数 先和堆顶的数交换int temp = data[i];data[i] = data[0];data[0] = temp;// 和堆顶交换后的数 和左右子树判断值 再决定和谁交换int t = 0;while (left(t) < n && data[left(t)] < data[t] || right(t) < n && data[right(t)] < data[t]) {// 右孩子比较小,交换if (right(t) < n && data[right(t)] < data[left(t)]) {temp = data[t];data[t] = data[right(t)];data[right(t)] = temp;t = right(t);} else {// 交换左孩子temp = data[t];data[t] = data[left(t)];data[left(t)] = temp;t = left(t);}}}/*** 找到前n个大的数* * @param n* @param data*/public void findTopN(int n, int[] data) {// 先构建堆buildHeap(n, data);// 堆n个数之后的数进行调整for (int i = n; i < data.length; i++) {adjust(i, n, data);}}public static void main(String[] args) {int[] data = { 99, 66, 23, 65, 12, 56, 1, 67, 88, 23, 567, 123, 321, 231, 342, 556, 666, 731, 466, 29 };System.out.println("构建数组前的数组为:" + Arrays.toString(data));TopN top = new TopN();top.buildHeap(7, data);System.out.println("构建数组后的数组为:" + Arrays.toString(data));top.findTopN(7, data);System.out.println("findTopN的数组为:" + Arrays.toString(data));}
}

测试结果:

java实现小顶堆 在指定数据中找出前n大的数相关推荐

  1. 10亿数据找出前100大的数据

    方法1:利用堆排实现 取前m个数,建立一个小根堆.建堆的时间复杂度为O(mlogm) 顺序读取后边的元素,如果该元素比堆顶的元素小,直接丢弃.如果大于堆顶的元素则替换它,然后调整堆,最坏的情况是每一次 ...

  2. PTA在一大堆数据中找出重复的是一件经常要做的事情。现在,我们要处理许多整数,在这些整数中,可能存在重复的数据。

    在一大堆数据中找出重复的是一件经常要做的事情.现在,我们要处理许多整数,在这些整数中,可能存在重复的数据. 你要写一个程序来做这件事情,读入数据,检查是否有重复的数据.如果有,输出"YES& ...

  3. 大顶堆,n个数中找最小的k个数

    package com.alo.offer;import java.util.Scanner;/*** n个数中找到最小的m个数 使用大顶堆* n个书中找到最大的m个数 使用小顶堆* @author ...

  4. 10亿数据找出前100大的数据(网易大数据面试算法题)

    精华在评论区.... 当时去面试的时候现场现写,憋了将近一个小时,用递归实现了,估计问题很多,不是人家怎么可能不要我,哈哈哈,开个玩笑: 思路就是新建一个长度为100数组array1,把前100个元素 ...

  5. 面试经典:链表中倒数第k个结点?如何从大量数据中找出高频词?

    记录两道面试题: 题目描述: 输入一个链表,输出该链表中倒数第k个结点.(单向链表) 拿到这个问题的时候自然而然会想到让链表从末尾开始next   K-1 次不就是第K-1个节点了么,但是必须要注意一 ...

  6. 大数据面试题——如何从大量数据中找出高频词

    问题描述: 有一个1GB大小的文件,文件里面每一行是一个词,每个词的大小不超过16B,内存大小限制为1MB,要求返回频数最高的100个词. 分析: 由于文件大小为1GB,而内存的大小只有1MB,因此不 ...

  7. 堆排序及从10亿个数据中找出最小或最大的10个数

    高频面试题目 一.堆排序 1.基础知识 * ------基本知识: * 1. 堆数据结构特征: * 大顶堆:所有父节点大于等于左右子节点,arr[i] >= arr[2i+1] &&am ...

  8. 大数据面试题——如何在大量的数据中找出不重复的数

    问题描述: 在2.5亿个整数中找出不重复的数,注意,内存不足以容纳2.5亿个整数. 分析解读: 方法一:分治法 采用hash的方法,把这2.5亿个数划分到更小的文件中,从而保证每个文件的大小不超过可用 ...

  9. 海量数据处理 大量数据中找出最大的前10个数 (Top K 问题)

    在工作中我们常遇到此类问题,从一个大量甚至海量的数据中取出前几个大的数.必须在海量的文章中取出点击量最大的10篇文章. 此类问题其实就是Top K问题. 给定一个数据(数据量海量 N),想找到前 K ...

最新文章

  1. python语言解释器的全部代码都是开源的_Python IDE和解释器的区别是什么?
  2. C#——委托(delegate)DEMO
  3. 10分钟免费开启全站https
  4. 高级筛选的以公式结果为条件
  5. ux和ui_从UI切换到UX设计
  6. 高性能mysql_事务及4种隔离级别
  7. P5718 【深基4.例2】找最小值
  8. centos 基础命令第一节
  9. HTML5 开源游戏引擎 LayaAir
  10. linux中mysql基本操作
  11. ad走线打过孔_ad走线时放置过孔
  12. 2022-2027年中国认证检验检测行业市场全景评估及发展战略研究报告
  13. R语言使用median函数计算dataframe指定数据列的中位数
  14. 【译】Linux不同的IO访问方式中,Scylla的选择和依据
  15. 解决小米手机安装失败(-108)错误
  16. 封装一个学生类Student(使用类与对象的方法)
  17. .NET/C# 生成二维码
  18. (附源码)SSM医疗健康查询系统JAVA计算机毕业设计项目
  19. 健身管理系统 -健身管理软件模板
  20. 股票量化分析工具QTYX使用攻略——高速版本地行情源(更新v2.5.4)

热门文章

  1. 作为一名程序员,如何开展自己的副业?月赚三万的真实故事
  2. 微积分基础知识:泰勒公式
  3. (转载)火狐浏览器禁用检查更新
  4. 算法导论第三版2.1答案
  5. 高斯消去法(python实现)
  6. Metasploit基本用法
  7. linux中rm命令的功能,Linux中的rm命令
  8. 动态规划LeetCode_1143
  9. 人工智能技术之农业革命
  10. 电影-魔幻之吻-后感