数据结构——堆的应用 Topk问题

2024-03-10 15:36

本文主要是介绍数据结构——堆的应用 Topk问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

💞💞 前言

hello hello~ ,这里是大耳朵土土垚~💖💖 ,欢迎大家点赞🥳🥳关注💥💥收藏🌹🌹🌹
在这里插入图片描述

💥个人主页:大耳朵土土垚的博客
💥 所属专栏:数据结构学习笔记 、C语言系列函数实现
💥对于数据结构顺序表、链表、堆有疑问的都可以在上面数据结构的专栏进行学习哦~ 有问题可以写在评论区或者私信我哦~

🥳🥳前面我们学习了利用堆进行排序,今天我们将继续介绍利用堆解决前k个最值的问题,Topk问题(在N个数中找出最大的前k个)在实际生活中也非常常见,💥💥比如店外卖时评分最高的前十家店铺,玩王者时英雄战力前十名等与排序排名有关的应用。

🥰🥰解题思路

正常思路 将这N个数建成一个大堆,然后Popk次,就可以找出最大的前k个 ;
💫💫但是如果N非常大以亿计(10亿个整数所占空间大概4G)那么就会非常耗时耗力,难以计算。

这里给出一种更好的解决办法:

①将前k个数建成小堆;(必须是小堆哦~)
②后面N-k个数依次比较,如果比堆顶的数据大,就替换它进堆
③然后将替换后的再向下调整使之重新成为一个小堆;
④最后这个小堆的值就是最大的前k个。

在写题之前我们先要创造N个数,可以通过c语言的文件操作以及随机生成函数来获得并写入文件中:

代码如下:

#include<time.h>
//创造N个数据
void CreatData()
{//造数据int n = 1000;srand(time(0));const char* file = "data.txt";FILE* fin = fopen(file, "w");if (fin == NULL){perror("fopen error");return;}for (int  i = 0; i < n; i++){int x = rand() % 10000;fprintf(fin, "%d\n", x);}fclose(fin);
}

✨✨这里使用了srand生成随机数需要包含time.h头文件;
int x = rand() % 10000;这个式子可以帮助我们生成10000以内的随机数;
fprintf可以帮助我们将生成的随机数写入到文件中(如下图生成了data文件):

在这里插入图片描述

所以生成文件后为了找到最大的前k个,我们可以手动改一些数据来验证后续代码的正确性:

在这里插入图片描述

这里手动改了5个,后面如果找出这五个最大的数就说明我们写的代码是正确的啦~🥳🥳
为了保证文件数据不被覆盖,我们在运行一次CreatData()函数之后就可以把它屏蔽掉了,此时已经生成了n个数据的文件data.txt了。


int main()
{//CreatData();//屏蔽PrintTopk(5, 1000);return 0;
}

Topk排序

造完数据后我们就可以利用之前学习过的堆来求出Topk啦

代码如下:

void PrintTopk(int k,int n)
{//打开文件const char* file = "data.txt";FILE* fout = fopen(file, "r");if (fout == NULL){perror("fopen error");return;}//创建顺序表开辟空间int* kminheap = (int*)malloc(sizeof(int) * k);if (kminheap == NULL){perror("malloc fail");return;}//从文件中读取k个数for (int i = 0; i < k; i++){fscanf(fout, "%d", &kminheap[i]);}//将读取的k个数创建为小堆//堆向下调整算法for (int i = (k - 2) / 2; i >= 0; i--){AdjustDown(kminheap, k, i);}//将剩余N-k个数依次与堆顶元素比较for (int i = 0; i < n - k; i++){int tmp = 0;fscanf(fout, "%d", &tmp);if (tmp > kminheap[0]){Swap(&tmp, &kminheap[0]);AdjustDown(kminheap, k, 0);}}//打印前k个元素for (int i = 0; i < k; i++){printf("%d\n", kminheap[i]);}
}

对于造小堆以及排序有疑问的可以看看土土的上篇博客🥰🥰——堆排序详解

运行代码如下:

int main()
{//CreatData();PrintTopk(5, 1000);return 0;
}

运行结果如下:
在这里插入图片描述

🎉🎉完全正确~是我们之前改的那五个数,说明我们的代码将它从1000个数中找了出来🥳🥳至此Topk问题得到解决 ~

✨✨这里再提一句,打印出来的虽然是n个数中的最大的k个但是我们发现打印的顺序是乱的,通过之前排序的学习,大家知道怎么将他们按顺序打印出来吗?有兴趣的小伙伴可以尝试一下~🥳🥳

结语

以上就是数据结构中利用堆排序求解Topk问题啦,关键在于对于堆排序的理解与运用~有疑问的小伙伴可以将问题打在评论区或者私信我哦 ~完结撒花 ~🥳🥳🎉🎉🎉

这篇关于数据结构——堆的应用 Topk问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/794693

相关文章

IDEA和GIT关于文件中LF和CRLF问题及解决

《IDEA和GIT关于文件中LF和CRLF问题及解决》文章总结:因IDEA默认使用CRLF换行符导致Shell脚本在Linux运行报错,需在编辑器和Git中统一为LF,通过调整Git的core.aut... 目录问题描述问题思考解决过程总结问题描述项目软件安装shell脚本上git仓库管理,但拉取后,上l

idea npm install很慢问题及解决(nodejs)

《ideanpminstall很慢问题及解决(nodejs)》npm安装速度慢可通过配置国内镜像源(如淘宝)、清理缓存及切换工具解决,建议设置全局镜像(npmconfigsetregistryht... 目录idea npm install很慢(nodejs)配置国内镜像源清理缓存总结idea npm in

pycharm跑python项目易出错的问题总结

《pycharm跑python项目易出错的问题总结》:本文主要介绍pycharm跑python项目易出错问题的相关资料,当你在PyCharm中运行Python程序时遇到报错,可以按照以下步骤进行排... 1. 一定不要在pycharm终端里面创建环境安装别人的项目子模块等,有可能出现的问题就是你不报错都安装

idea突然报错Malformed \uxxxx encoding问题及解决

《idea突然报错Malformeduxxxxencoding问题及解决》Maven项目在切换Git分支时报错,提示project元素为描述符根元素,解决方法:删除Maven仓库中的resolv... 目www.chinasem.cn录问题解决方式总结问题idea 上的 maven China编程项目突然报错,是

Python爬虫HTTPS使用requests,httpx,aiohttp实战中的证书异步等问题

《Python爬虫HTTPS使用requests,httpx,aiohttp实战中的证书异步等问题》在爬虫工程里,“HTTPS”是绕不开的话题,HTTPS为传输加密提供保护,同时也给爬虫带来证书校验、... 目录一、核心问题与优先级检查(先问三件事)二、基础示例:requests 与证书处理三、高并发选型:

利用Python操作Word文档页码的实际应用

《利用Python操作Word文档页码的实际应用》在撰写长篇文档时,经常需要将文档分成多个节,每个节都需要单独的页码,下面:本文主要介绍利用Python操作Word文档页码的相关资料,文中通过代码... 目录需求:文档详情:要求:该程序的功能是:总结需求:一次性处理24个文档的页码。文档详情:1、每个

前端导出Excel文件出现乱码或文件损坏问题的解决办法

《前端导出Excel文件出现乱码或文件损坏问题的解决办法》在现代网页应用程序中,前端有时需要与后端进行数据交互,包括下载文件,:本文主要介绍前端导出Excel文件出现乱码或文件损坏问题的解决办法,... 目录1. 检查后端返回的数据格式2. 前端正确处理二进制数据方案 1:直接下载(推荐)方案 2:手动构造

Python绘制TSP、VRP问题求解结果图全过程

《Python绘制TSP、VRP问题求解结果图全过程》本文介绍用Python绘制TSP和VRP问题的静态与动态结果图,静态图展示路径,动态图通过matplotlib.animation模块实现动画效果... 目录一、静态图二、动态图总结【代码】python绘制TSP、VRP问题求解结果图(包含静态图与动态图

MyBatis/MyBatis-Plus同事务循环调用存储过程获取主键重复问题分析及解决

《MyBatis/MyBatis-Plus同事务循环调用存储过程获取主键重复问题分析及解决》MyBatis默认开启一级缓存,同一事务中循环调用查询方法时会重复使用缓存数据,导致获取的序列主键值均为1,... 目录问题原因解决办法如果是存储过程总结问题myBATis有如下代码获取序列作为主键IdMappe

Java中的分布式系统开发基于 Zookeeper 与 Dubbo 的应用案例解析

《Java中的分布式系统开发基于Zookeeper与Dubbo的应用案例解析》本文将通过实际案例,带你走进基于Zookeeper与Dubbo的分布式系统开发,本文通过实例代码给大家介绍的非常详... 目录Java 中的分布式系统开发基于 Zookeeper 与 Dubbo 的应用案例一、分布式系统中的挑战二