java实现小顶堆 在指定数据中找出前n大的数
小顶堆:
我们利用的特性:每个节点都比左右孩子小
图示:
取数组前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大的数相关推荐
- 10亿数据找出前100大的数据
方法1:利用堆排实现 取前m个数,建立一个小根堆.建堆的时间复杂度为O(mlogm) 顺序读取后边的元素,如果该元素比堆顶的元素小,直接丢弃.如果大于堆顶的元素则替换它,然后调整堆,最坏的情况是每一次 ...
- PTA在一大堆数据中找出重复的是一件经常要做的事情。现在,我们要处理许多整数,在这些整数中,可能存在重复的数据。
在一大堆数据中找出重复的是一件经常要做的事情.现在,我们要处理许多整数,在这些整数中,可能存在重复的数据. 你要写一个程序来做这件事情,读入数据,检查是否有重复的数据.如果有,输出"YES& ...
- 大顶堆,n个数中找最小的k个数
package com.alo.offer;import java.util.Scanner;/*** n个数中找到最小的m个数 使用大顶堆* n个书中找到最大的m个数 使用小顶堆* @author ...
- 10亿数据找出前100大的数据(网易大数据面试算法题)
精华在评论区.... 当时去面试的时候现场现写,憋了将近一个小时,用递归实现了,估计问题很多,不是人家怎么可能不要我,哈哈哈,开个玩笑: 思路就是新建一个长度为100数组array1,把前100个元素 ...
- 面试经典:链表中倒数第k个结点?如何从大量数据中找出高频词?
记录两道面试题: 题目描述: 输入一个链表,输出该链表中倒数第k个结点.(单向链表) 拿到这个问题的时候自然而然会想到让链表从末尾开始next K-1 次不就是第K-1个节点了么,但是必须要注意一 ...
- 大数据面试题——如何从大量数据中找出高频词
问题描述: 有一个1GB大小的文件,文件里面每一行是一个词,每个词的大小不超过16B,内存大小限制为1MB,要求返回频数最高的100个词. 分析: 由于文件大小为1GB,而内存的大小只有1MB,因此不 ...
- 堆排序及从10亿个数据中找出最小或最大的10个数
高频面试题目 一.堆排序 1.基础知识 * ------基本知识: * 1. 堆数据结构特征: * 大顶堆:所有父节点大于等于左右子节点,arr[i] >= arr[2i+1] &&am ...
- 大数据面试题——如何在大量的数据中找出不重复的数
问题描述: 在2.5亿个整数中找出不重复的数,注意,内存不足以容纳2.5亿个整数. 分析解读: 方法一:分治法 采用hash的方法,把这2.5亿个数划分到更小的文件中,从而保证每个文件的大小不超过可用 ...
- 海量数据处理 大量数据中找出最大的前10个数 (Top K 问题)
在工作中我们常遇到此类问题,从一个大量甚至海量的数据中取出前几个大的数.必须在海量的文章中取出点击量最大的10篇文章. 此类问题其实就是Top K问题. 给定一个数据(数据量海量 N),想找到前 K ...
最新文章
- python语言解释器的全部代码都是开源的_Python IDE和解释器的区别是什么?
- C#——委托(delegate)DEMO
- 10分钟免费开启全站https
- 高级筛选的以公式结果为条件
- ux和ui_从UI切换到UX设计
- 高性能mysql_事务及4种隔离级别
- P5718 【深基4.例2】找最小值
- centos 基础命令第一节
- HTML5 开源游戏引擎 LayaAir
- linux中mysql基本操作
- ad走线打过孔_ad走线时放置过孔
- 2022-2027年中国认证检验检测行业市场全景评估及发展战略研究报告
- R语言使用median函数计算dataframe指定数据列的中位数
- 【译】Linux不同的IO访问方式中,Scylla的选择和依据
- 解决小米手机安装失败(-108)错误
- 封装一个学生类Student(使用类与对象的方法)
- .NET/C# 生成二维码
- (附源码)SSM医疗健康查询系统JAVA计算机毕业设计项目
- 健身管理系统 -健身管理软件模板
- 股票量化分析工具QTYX使用攻略——高速版本地行情源(更新v2.5.4)