堆与TopK问题分析

TopK问题

题目及思路分析

所谓TopK问题,在一组数据中找出前K个最大或者最小的数值,而使用TopK问题的解决思路的问题一般数据个数都比较大,如果直接用数组,则会导致数据无法一次性加载到内存从而难以比较,难者甚至因为数据过大只能存储到磁盘中,导致无法排列数据,而TopK的合理解决思路如下(此处以找前K个最大的数为例):

整个数据很大,所以可能可以存储到内存中,也可能存储到磁盘中,所以不会一次性将磁盘中的数据全部加载到内存中进行管理

第一步先抽取数据中的前K个值建立一个小堆,因为小堆的结构满足最小的数值一定在根节点,而比根节点大的数值一定会排在根节点的后面

第二步再将剩余的N-K个数值依次与小堆的根节点数据进行比较,如果比根节点大就覆盖根节点并恢复成小堆。

此处的主要思路是:因为前K个最大数值肯定比其余数值都大,但是不需要保证在第一步中一定取出的是最大的数值,所以每一次遇到一个属于前K个最大数值的数据时肯定会顶替掉根节点进入小堆重新排列,此过程一直持续到最后没有数据比根节点(前K个最大的数值中的最小值)的数据还要大的时候就结束

第三步:当没有数据再进堆时,此时的小堆即为前K个最大的数值

图解思路

下面是过程示意图:

//以下面的数组为例
int data[] = { 111,333,89,22,45,276,4578,4673,2397,311,1231};
//假设需要取出最大的前5个数值

参考代码

#define _CRT_SECURE_NO_WARNINGS 1#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <time.h>void swap(int* num1, int* num2)
{int tmp = *num1;*num1 = *num2;*num2 = tmp;
}//向下调整算法
void AdjustDown(int* data, int sz, int parent)
{int child = parent * 2 + 1;while (child < sz){if (child + 1 < sz && data[child] > data[child + 1]) {child++;}if (data[child] < data[parent]){swap(&data[child], &data[parent]);parent = child;child = parent * 2 + 1;}else{break;}}
}//向文件中写数据
void createData()
{//创建种子srand((unsigned int)time(0));//创建数据文件FILE* fin = fopen("data.txt", "w");assert(fin);//向文件中写数据int num = 10000;//数据个数for (int i = 0; i < num; i++){int val = rand() % 10000;//生成10000以内的数据fprintf(fin, "%d\n", val);}fclose(fin);
}//使用堆排序对小堆数据进行降序排序
void HeapSort(int* data, int sz)
{for (int i = sz - 1; i >= 0; i--){swap(&data[0], &data[i]);AdjustDown(data, i, 0);}
}//获取TopK数据
void printTopKnum(int k)
{//打开文件FILE* fout = fopen("data.txt", "r");//取出前K个数值建立小堆int* arr = (int*)malloc(sizeof(int) * k);assert(arr);//从文件中读数据放入数组中for (int i = 0; i < k; i++){fscanf(fout, "%d", &arr[i]);}//建立小堆for (int i = (k - 2)/2; i >= 0; i--){AdjustDown(arr, k, i);}//比较剩余的N-K个数值while (!feof(fout)){int val = 0;fscanf(fout, "%d", &val);if (val > arr[0]){arr[0] = val;AdjustDown(arr, k, 0);}}fclose(fout);//使用堆排序对小堆数据进行升序排序HeapSort(arr, k);//打印小堆的数据for (int i = 0; i < k; i++){printf("%d ", arr[i]);}
}int main()
{//向文件中写数据createData();//获取TopK数据int k = 10;printTopKnum(k);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/503918.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++之函数,指针

函数 1&#xff0c;函数概述 作用&#xff1a;将一段经常使用的代码封装起来&#xff0c;减少重复代码 一个较大的程序&#xff0c;一般分为若干份程序块&#xff0c;每个模块实现特定的功能 2&#xff0c;函数的定义 函数的定义一般有五个步骤&#xff1a; 1&#xff0c…

MATLAB中function_handle函数用法

目录 说明 创建对象 示例 命名函数求积分 匿名函数求积分 function_handle函数所表示的是函数的句柄。 说明 函数句柄是一种表示函数的 MATLAB 数据类型。函数句柄的典型用法是将函数传递给另一个函数。例如&#xff0c;可以将函数句柄用作基于某个值范围计算数学表达式的…

c++基础知识补充4

单独使用词汇 using std::cout; 隐式类型转换型初始化&#xff1a;如A a1,,此时可以形象地理解为int i1;double ji;&#xff0c;此时1可以认为创建了一个值为1的临时对象&#xff0c;然后对目标对象进行赋值&#xff0c;当对象为多参数时&#xff0c;使用&#xff08;1&#xf…

微信小程序云开发教程——墨刀原型工具入门(添加交互事件)

引言 作为一个小白&#xff0c;小北要怎么在短时间内快速学会微信小程序原型设计&#xff1f; “时间紧&#xff0c;任务重”&#xff0c;这意味着学习时必须把握微信小程序原型设计中的重点、难点&#xff0c;而非面面俱到。 要在短时间内理解、掌握一个工具的使用&#xf…

【多线程】CAS详解

目录 &#x1f334;什么是 CAS&#x1f338;CAS 伪代码 &#x1f38d;CAS 是怎么实现的&#x1f340;CAS 有哪些应⽤&#x1f338;实现原子类&#x1f338;实现自旋锁 &#x1f333;CAS 的 ABA 问题&#x1f338;**什么是 ABA 问题**&#xff1f;&#x1f338;ABA 问题引来的 B…

笔记73:ROS中的各种消息包

参考视频&#xff1a; 33.ROS 的标准消息包 std_msgs_哔哩哔哩_bilibili 34. ROS 中的几何包 geometry_msgs 和 传感器包 sensor_msgs_哔哩哔哩_bilibili 标准消息包&#xff1a;std_msgs常用消息包&#xff1a;common_msgs导航消息包&#xff1a;nav_msgs几何消息包&#xf…

Mysql主从备份

主从复制概述 将主服务器的binlog日志复制到从服务器上执行一遍&#xff0c;达到主从数据的一致状态&#xff0c;称之为主从复制。一句话表示就是&#xff0c;主数据库做什么&#xff0c;从数据库就跟着做什么。 为什么要使用主从复制 为实现服务器负载均衡/读写分离做铺垫&…

Cocos Creator 3.8.x 后效处理(前向渲染)

关于怎么开启后效效果我这里不再赘述&#xff0c;可以前往Cocos官方文档查看具体细节&#xff1a;后效处理官网 下面讲一下怎么自己定义一个后处理效果&#xff0c;想添加自己的后效处理的话只需要在postProcess节点下添加一个BlitScreen 组件即可&#xff0c;然后自己去添加自…

CentOS下MySQL的安装以及配置环境

CentOS下MySQL的安装以及配置环境 &#x1f4df;作者主页&#xff1a;慢热的陕西人 &#x1f334;专栏链接&#xff1a;MySQL &#x1f4e3;欢迎各位大佬&#x1f44d;点赞&#x1f525;关注&#x1f693;收藏&#xff0c;&#x1f349;留言 本博客主要内容讲解了CentOS环境下的…

不同微服务之间如何实现远程调用?一个简单示例告诉你

目录 1、服务拆分原则 2、服务拆分示例 2.1、初始化数据库 2.2、导入demo工程 2.3、测试 3、实现远程调用 3.1、需求 3.2、注册RestTemplate 3.3、实现远程调用 4、提供者与消费者 5、代码免费分享 &#x1f343;作者介绍&#xff1a;双非本科大三网络工程专业在读…

【重要公告】对BSV警报系统AS的释义

​​发表时间&#xff1a;2024年2月15日 由BSV区块链协会开发并管理的BSV警报系统&#xff08;Alert System&#xff0c;以下简称“AS”&#xff09;是BSV网络的重要组件。它是一个复杂的系统&#xff0c;主要职能是在BSV区块链网络内发布信息。这些信息通常与网络访问规则NAR相…

Flutter中的三棵树

Widget Tree&#xff1a; 页面配置信息。 Element Tree&#xff1a; Widget tree的实例化对象&#xff0c;创建出renderObject&#xff0c;并关联到element.renderobject属性上&#xff0c;最后完成RenderObject Tree的创建。 RenderObject Tree&#xff1a;完成布局和图层绘制…