在1000万整数中找到前100个最大的数 算法
这一段时间写毕业设计,遇到一些大数据的情况,想起之前和同学讨论的最优算法,写一下相关思路。
在1000万整数中寻找最大的100个数,最优的算法是建一个大小为100的小顶堆(堆排序需要建立完全二叉树),先取出前100个数并构建小顶堆,然后遍历数据与小顶堆的堆顶相比,比堆顶小直接丢弃,比堆顶大则替换堆顶,并重新构建这个堆。
堆排序
先介绍一下完全二叉树:除了最后一层之外的其他每一层都被完全填充,并且所有结点都保持向左对齐
堆排序:堆排序是将数据看成是完全二叉树、根据完全二叉树的特性来进行排序的一种算法
- 最小堆要求节点元素都不大于其左右孩子
- 那么处于最小堆的根节点的元素一定是这个堆中的最小值
模拟一次最小堆排序的过程:
假如有
int[] arr = new int[]{3,6,8,7,0,1,10,4,2};
第一步:建立完全二叉树
从上图可以看出,第n个节点的左子节点为2*n+1,右子节点为2*n+2
第二步:从 arr.length/2 - 1 就是最后一个叶子节点的父节点开始,比较其左右子节点,找到最小的,并与其交换,一直到根节点:
这样一个最小堆就建立完成。
相关代码(java):
/*** 建堆** @param arr 看作是完全二叉树* @param currentNode 当前父节点位置* @param size 节点总数*/
public class HeapSortTest {public static void main(String[] args) {int[] arr = new int[]{3,6,8,7,0,1,10,4,2};int start = arr.length/2 -1;for (int i = start; i >= 0 ; i--){minHeap(arr, arr.length, i);}System.out.println(Arrays.toString(arr));}public static void minHeap(int []arr, int size, int currentNode){//左子树和右字数的位置int leftNode = currentNode * 2 + 1;int rightNode = currentNode * 2 + 2;//把当前父节点位置看成是最小的int min = currentNode;//比较左右节点if (leftNode < size && arr[leftNode] < arr[min]){max = leftNode;}if (rightNode < size && arr[rightNode] < arr[min]){max = rightNode;}//如果比父节点小,就交换if (min != currentNode){int temp = arr[min];arr[min] = arr[currentNode];arr[currentNode] = temp;//继续比较,直到完成一次建堆minHeap(arr, size, min);}}
}
对于1000万个数:
public static int N = 100; //Top100public static int LEN = 10000000; //1千万个整数public static int arrs[] = new int[LEN];public static int result[] = new int[N]; //在内存维护一个长度为N的小顶堆public static int len = result.length;//堆中元素的有效元素 heapSize<=lenpublic static int heapSize = len;public static void main(String[] args) {//生成随机数组for(int i = 0;i<LEN;i++){arrs[i] = new Random().nextInt(999999999);}//构建初始堆for(int i = 0;i<N;i++){result[i] = arrs[i];}//构建小顶堆long start =System.currentTimeMillis();buildMinHeap();for(int i = N;i<LEN;i++){if(arrs[i] > result[0]){result[0] = arrs[i];minHeap(arrs, N, 0);}}System.out.println(LEN+"个数,求Top"+N+",耗时"+(System.currentTimeMillis()-start)+"毫秒");print();}/*** 自底向上构建小堆*/public static void buildMinHeap(){int size = len / 2 -1 ; //最后一个非叶子节点for(int i = size;i>=0;i--){minHeap(arrs, N, i);}
一次堆排序重整的时间复杂度:logn (第一次建堆是从下到上,重整堆是从上到下,每次数据替换时,最差情况是堆顶数据为最大,依次向下比较交换,直到叶子节点,比较交换次数为logn 即为构建二叉树层数)。
最差情况为每次都替换,即时间复杂度为10000000*log100
参考资料:https://www.cnblogs.com/Java3y/p/8639937.html
在1000万整数中找到前100个最大的数 算法相关推荐
- 如何在10亿个数中找到前1000大的数?
2019独角兽企业重金招聘Python工程师标准>>> 如何在10亿个数中找到前1000大的数? 定位 TopN问题 算法 排序不是最优的解决方案: 可以考虑分治法: 类似快速排序中 ...
- 《程序员代码面试指南》第七章 位运算 在其他数都出现k 次的数组中找到只出现一次的数...
题目 在其他数都出现k 次的数组中找到只出现一次的数 java 代码 package com.lizhouwei.chapter7;/*** @Description: 在其他数都出现k 次的数组中找 ...
- C语言在BST中找到最接近目标的值的算法(附完整源码)
C语言在BST中找到最接近目标的值的算法 C语言在BST中找到最接近目标的值的算法完整源码(定义,实现,main函数测试) C语言在BST中找到最接近目标的值的算法完整源码(定义,实现,main函数测 ...
- C++在数字N中找到精确除以N的数字的算法(附完整源码)
C++在数字N中找到精确除以N的数字的算法 C++在数字N中找到精确除以N的数字的算法完整源码(定义,实现,main函数测试) C++在数字N中找到精确除以N的数字的算法完整源码(定义,实现,main ...
- C++在数字向量中找到出现奇数次的数字的算法实现(附完整源码)
C++在数字向量中找到出现奇数次的数字的算法实现 C++在数字向量中找到出现奇数次的数字的算法实现完整源码(定义,实现,main函数测试) C++在数字向量中找到出现奇数次的数字的算法实现完整源码(定 ...
- c语言随机生成n个数求最小值,C语言程序:从N个数中随机取出100个不同的数
/**你题目中的N个数至少得大于100吧.下面的程序N个数是随机生成 你的N个数是?同时这个程序有错误的话请告诉我. */ /* *从N个数中随机取出100个不同的数 *@author:banxi19 ...
- 学霸用 Python 分析相亲网站数据,在两万异性中找到真爱!
微信搜 "GitHubDaily" 点关注 设为 "星标",每天带你逛 GitHub! 转自大数据文摘 来源:Wired 编译:啤酒泡泡.张大笔茹.张睿毅.牛婉 ...
- 只需五步!哈佛学霸教你用Python分析相亲网站数据,在两万异性中找到真爱
大数据文摘出品 来源:Wired 编译:啤酒泡泡.张大笔茹.张睿毅.牛婉杨 想脱单?那还不容易! 如果身在美国,就像其余四千万单身男人一样,注册一下Match.com, J-Date和OkCupid等 ...
- 【面试被虐】如何只用2GB内存从20亿,40亿,80亿个整数中找到出现次数最多的数?...
这几天小秋去面试了,不过最近小秋学习了不少和位算法相关文章,例如 [面试现场]如何判断一个数是否在40亿个整数中? [算法技巧]位运算装逼指南 对于算法题还是有点信心的,,,,于是,发现了如下对话. ...
最新文章
- [转] Transformer图解
- C++学习笔记(二)——交换函数(swap)
- python getattr_详解 Python 的二元算术运算,为什么说减法只是语法糖?
- Singing Superstar HDU - 7064
- 支持ps2021 Document Star证件照大师 Mac插件2.0
- 喜庆新年春节 祝贺语词 艺术字体PSD分层素材
- 代码流程图_助力理解js代码,进阶JavaScript代码能力——js2flowchart
- 医学AI又一突破,微软开源生物医学NLP基准:BLURB
- linux 如何开启shell,linux下开启Shell命令
- 动易 dw css不对,动易模板常用CSS修改实际操作技巧
- python结课设计力学方面_课程设计心得
- ie浏览器调用本地文件无反应_ie上传附件没有反应怎么办_解决ie浏览器上传附件没有反应的方法...
- Spanning-tree生成树协议
- 设计模式----单利模式
- 【环境搭建】Docker镜像相关操作(切换镜像源、查询、获取、查看、创建、上传、保存、删除等)
- 使用LaTeX表示数学方程(附源码)
- C语言:求高次方数的尾数
- IDEA服务器端JQuery框架加载失败--已解决
- 怎樣制作线段动画_教您怎样才能演示图形平移过程?
- 个人空间的编辑个人资料案例(简单介绍 仅供参考)