news 2026/6/23 18:22:50

海量数据中找出最大的前100个(find_topk)最小堆算法

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
海量数据中找出最大的前100个(find_topk)最小堆算法

我来帮你实现这个寻找前100个最大数据的算法。这个算法的时间复杂度是O(n log 100),空间复杂度是O(100)。

C++实现

#include<iostream>#include<vector>#include<queue>#include<functional>#include<random>usingnamespacestd;// 寻找前k个最大元素的算法vector<int>findTopK(constvector<int>&nums,intk){if(nums.size()<=k){vector<int>result(nums.begin(),nums.end());returnresult;}// 创建最小堆priority_queue<int,vector<int>,greater<int>>minHeap;// 步骤1: 插入前k个元素for(inti=0;i<k;i++){minHeap.push(nums[i]);}// 步骤2-3: 遍历剩余元素,维护堆for(size_t i=k;i<nums.size();i++){if(nums[i]>minHeap.top()){minHeap.pop();// 弹出堆顶minHeap.push(nums[i]);// 插入当前元素}}// 步骤4: 堆中元素即为前k个最大数据vector<int>result;while(!minHeap.empty()){result.push_back(minHeap.top());minHeap.pop();}returnresult;}intmain(){// 生成测试数据vector<int>data(1000);random_device rd;mt19937gen(rd());uniform_int_distribution<>dis(1,10000);for(inti=0;i<1000;i++){data[i]=dis(gen);}intk=100;vector<int>topK=findTopK(data,k);cout<<"前"<<k<<"个最大元素:"<<endl;for(size_t i=0;i<topK.size();i++){cout<<topK[i]<<" ";if((i+1)%10==0)cout<<endl;}cout<<endl;return0;}

Python实现

importheapqimportrandomfromtypingimportListdeffind_top_k(nums:List[int],k:int)->List[int]:""" 寻找前k个最大元素的算法 实现步骤: 1. 创建一个最小堆并将前k个数据插入堆中 2. 遍历剩余的数据,如果当前数据比堆顶大,就替换堆顶元素 3. 继续遍历所有数据,确保堆中保留的是最大的k个数据 4. 遍历完成后,堆中的元素就是前k个最大的数据 """iflen(nums)<=k:returnsorted(nums,reverse=True)# 步骤1: 创建最小堆并插入前k个元素min_heap=nums[:k]heapq.heapify(min_heap)# 建立最小堆# 步骤2-3: 遍历剩余元素,维护堆fornuminnums[k:]:ifnum>min_heap[0]:# 如果当前元素比堆顶大# 弹出堆顶,插入当前元素heapq.heapreplace(min_heap,num)# 步骤4: 堆中元素即为前k个最大数据# 堆是最小堆,需要排序后返回result=sorted(min_heap,reverse=True)returnresultdeffind_top_k_alternative(nums:List[int],k:int)->List[int]:"""另一种实现方式,更清晰地体现算法步骤"""iflen(nums)<=k:returnsorted(nums,reverse=True)# 步骤1: 创建最小堆并插入前k个元素min_heap=[]foriinrange(k):heapq.heappush(min_heap,nums[i])# 步骤2-3: 遍历剩余数据foriinrange(k,len(nums)):ifnums[i]>min_heap[0]:# 比堆顶大# 我就往堆里面插heapq.heappop(min_heap)# 弹出堆顶heapq.heappush(min_heap,nums[i])# 插入当前数据# 步骤4: 返回结果returnsorted(min_heap,reverse=True)defmain():# 生成测试数据random.seed(42)data=[random.randint(1,10000)for_inrange(1000)]k=100# 使用方法1top_k=find_top_k(data,k)print(f"前{k}个最大元素:")fori,numinenumerate(top_k,1):print(f"{num:6d}",end=" ")ifi%10==0:print()print()# 验证结果正确性sorted_data=sorted(data,reverse=True)[:k]print(f"算法结果是否正确:{top_k==sorted_data}")# 使用方法2top_k2=find_top_k_alternative(data,k)print(f"方法2结果是否正确:{sorted(top_k2)==sorted(top_k)}")if__name__=="__main__":main()

算法复杂度分析

  • 时间复杂度: O(n log k),其中n是总数据量,k=100
  • 空间复杂度: O(k),只需要维护大小为100的堆

关键点说明

  1. 使用最小堆的原因:我们想要最大的k个元素,使用最小堆可以让我们在O(1)时间内知道当前堆中最小的元素
  2. 堆顶的作用:堆顶始终是当前堆中最小的元素,也就是第k大的候选者
  3. 替换条件:只有当新元素大于堆顶时,才进行替换,确保堆中始终是见过的最大的k个元素
  4. “我就往堆里面插”:这个操作在代码中体现为
    "heapq.heapreplace()"或先pop再push的操作

两种实现方式都可以,Python版本提供了两种写法:

    “find_top_k”:使用
    “heapq.heapreplace()”,更简洁

    “find_top_k_alternative”:分步操作,更清晰地体现算法步骤

    版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
    网站建设 2026/6/22 23:24:02

    Claude Code Router多模型集成实战:打造智能开发工作流

    Claude Code Router多模型集成实战&#xff1a;打造智能开发工作流 【免费下载链接】claude-code-router Use Claude Code without an Anthropics account and route it to another LLM provider 项目地址: https://gitcode.com/GitHub_Trending/cl/claude-code-router …

    作者头像 李华
    网站建设 2026/6/23 18:19:58

    水稻病害检测(YOLO数据集,多分类,稻瘟病、纹枯病、褐斑病、枯心病、霜霉病、水稻细菌性条纹斑病、稻苞虫)

    是自己利用LabelImg工具进行手工标注&#xff0c;数据集制作不易&#xff0c;请尊重版权&#xff08;稻瘟病、纹枯病、褐斑病、枯心病、霜霉病、水稻细菌性条纹斑病、稻苞虫&#xff09; 如果需要yolv8检测模型和数据集放在一起的压缩包&#xff0c;可以关注&#xff1a;最新最…

    作者头像 李华
    网站建设 2026/6/23 18:19:06

    ABB机器人省气装置在薄板焊接中的实际效果

    在现代制造业中&#xff0c;随着对产品质量和生产效率要求的不断提高&#xff0c;自动化焊接技术逐渐取代了传统的人工操作。ABB焊接机器人因其高精度、稳定性和灵活性&#xff0c;在多个工业领域得到了广泛应用。特别是在薄板焊接中&#xff0c;ABB焊接机器人的表现尤为突出。…

    作者头像 李华
    网站建设 2026/6/23 15:54:30

    京东Java面试被问:ZGC的染色指针如何实现?内存屏障如何处理?

    1. 传统GC的内存管理问题text传统GC标记对象方式&#xff1a; [对象头] [标记位] → 需要修改对象内存 问题&#xff1a;标记阶段需要STW&#xff0c;大堆停顿时间长2. ZGC的核心创新&#xff1a;元数据外置textZGC方案&#xff1a; [对象指针] [元数据标记] → 不修改对象本…

    作者头像 李华
    网站建设 2026/6/23 14:50:52

    硬件 - 高速协议设计整合

    目录 1.DDR 1.1 DDR设计规范概览 1.2 DDR PCB Layout要求 ​​​​​​​ 1.3 设计审批流程 ​​​​​​​ 1.4 常见错误以及防范 ------------------------------------------------------------------------------------------------------------------------ 2.…

    作者头像 李华
    网站建设 2026/6/23 14:52:47

    Vue3如何设计百万文件上传的进度监控界面?

    天津XX软件公司大文件传输系统前端技术方案&#xff08;第一人称视角&#xff09; 一、技术选型与架构设计 作为前端负责人&#xff0c;我主导了基于Vue3 TypeScript的模块化架构设计&#xff0c;核心解决以下痛点&#xff1a; 浏览器兼容性&#xff1a;通过分层适配策略覆…

    作者头像 李华