[ 数据结构-C实现 ] 用堆解决TopK问题
TopK问题的引入:想必大家在玩王者农药的时候都遇到过xxx市第xxx韩信,xxx区第xxx赵云。或者说大家今天懒得做饭,想点个外卖,于是乎大家打开美团App,假如说想吃汉堡,大家不知道哪家汉堡好吃,选择了一项叫按评分优先排序,选择排名靠前的店购买。学校有专业前10名。企业有世界500强等等等。这些问题都要对大量数据进行排序,选出较大的K个数据,这里就需要使用TopK算法来解决此类问题。
目录
1.什么是TopK问题?
1.1Top-k问题的基本思路
2.Top-K问题逻辑分析
2.1建堆--用a中前K个元素建堆
2.2将剩下的n-k个元素依次与堆顶的元素比较,不满足的替换
2.3打印堆
3.Top-K代码实现
4.Top-K问题举例实现
完整代码:
结果演示:
1.什么是TopK问题?
Top-K问题:即求数据结合中前K个最大的元素或者最小的元素,一般情况下数据量都比较大。
比如:专业前10名、世界500强、富豪榜、游戏中前100的活跃玩家等。
1.1Top-k问题的基本思路
(1)用数据集合中前K个元素建堆
~如果要求前K个最大的元素,则建立小堆
~如果要求前K个最小的元素,则建立大堆
(2)用剩余N-K个元素依次与堆顶的元素来比较(以求前K个最大元素举例),由于我们建立的是小堆,小堆堆顶元素是堆中最小的元素,因此我们比较元素如果大于堆顶元素,就替换堆顶元素,重新建小堆,如果小于堆顶元素则不能入堆,让下一个元素再进行比较,以此类推。
(3)待剩余N-K个元素依次与堆顶元素比较完后,堆中剩余的K个元素就是所求的前K个最小或者最大的元素。
2.Top-K问题逻辑分析
void PrintTopK(int* a, int n, int k)
{//1.建堆--用a中前K个元素建堆//2.将剩下的n-k个元素依次与堆顶元素交换,不满则替换//3.打印堆}
大致思路就可以分为这三步,我们一步一步进行分析:
2.1建堆--用a中前K个元素建堆
在此我们假设要求前K个较大的数字,因此我们要建立小堆。
过程:
1、我们开辟一个K个元素大小的空间。
2、我们让前K个元素组成对,数组自身建堆。使用向下调整建堆。(向下调整建堆不熟悉的小伙伴可以戳这里复习~~)
实现代码如下:
//1.建堆--用a中前K个元素建堆int* kminHeap = (int*)malloc(sizeof(int) * k);assert(kminHeap);for (int i = 0; i < k; i++){kminHeap[i] = a[i];}//建小堆for (int j = (k - 1 - 1) / 2; j >= 0; --j){AdjustDown(kminHeap, k, j);}
2.2将剩下的n-k个元素依次与堆顶的元素比较,不满足的替换
过程:
1、由于我们建立的是小堆,堆顶元素是堆中最小的元素,让进来的元素依次和堆顶元素比较。
2、如果这个元素大于堆顶数据,就交换。不满足就不交换。
3、若交换,使用向下调整重新建堆,让最小的数据放在堆顶。
4、当n-k个数据全部遍历完后,堆中的数据就是前K个较大的数据
for (int i = k; i < n; ++i){if (a[i] > kminHeap[0]){kminHeap[0] = a[i];AdjustDown(kminHeap, k, 0);}}
2.3打印堆
for (int i = 0; i < k; ++i){printf("%d ", kminHeap[i]);}printf("\n");free(kminHeap);
3.Top-K代码实现
void PrintTopK(int* a, int n, int k)
{//1.建堆--用a中前K个元素建堆int* kminHeap = (int*)malloc(sizeof(int) * k);assert(kminHeap);for (int i = 0; i < k; i++){kminHeap[i] = a[i];}//建小堆for (int j = (k - 1 - 1) / 2; j >= 0; --j){AdjustDown(kminHeap, k, j);}//2.将剩下的n-k个元素依次与堆顶元素交换,不满则替换for (int i = k; i < n; ++i){if (a[i] > kminHeap[0]){kminHeap[0] = a[i];AdjustDown(kminHeap, k, 0);}}//3.打印堆for (int i = 0; i < k; ++i){printf("%d ", kminHeap[i]);}printf("\n");free(kminHeap);
}
4.Top-K问题举例实现
我们编写一个数据,所有的值生成随机值,模上1000000,因此这个数组a中的所有值肯定小于等于1000000。我们再任意更改10个值大于1000000。我们这时选出Top-10大的数据。如果我们选出的数字是我们赋值的那几个,说明Top-K问题就解决了。
void TestTopK()
{int n = 10000;int* a = (int*)malloc(sizeof(int) * n);srand(time(0));for (size_t i = 0; i < n; ++i){a[i] = rand() % 1000000;}a[5] = 1000000 + 1;a[1231] = 1000000 + 2;a[531] = 1000000 + 3;a[5121] = 1000000 + 4;a[115] = 1000000 + 5;a[2305] = 1000000 + 6;a[99] = 1000000 + 7;a[76] = 1000000 + 8;a[423] = 1000000 + 9;a[0] = 1000000 + 1000;PrintTopK(a, n, 10);
}
完整代码:
void PrintTopK(int* a, int n, int k)
{//1.建堆--用a中前K个元素建堆int* kminHeap = (int*)malloc(sizeof(int) * k);assert(kminHeap);for (int i = 0; i < k; i++){kminHeap[i] = a[i];}//建小堆for (int j = (k - 1 - 1) / 2; j >= 0; --j){AdjustDown(kminHeap, k, j);}//2.将剩下的n-k个元素依次与堆顶元素交换,不满则替换for (int i = k; i < n; ++i){if (a[i] > kminHeap[0]){kminHeap[0] = a[i];AdjustDown(kminHeap, k, 0);}}//3.打印堆for (int i = 0; i < k; ++i){printf("%d ", kminHeap[i]);}printf("\n");free(kminHeap);
}void TestTopK()
{int n = 10000;int* a = (int*)malloc(sizeof(int) * n);srand(time(0));for (size_t i = 0; i < n; ++i){a[i] = rand() % 1000000;}a[5] = 1000000 + 1;a[1231] = 1000000 + 2;a[531] = 1000000 + 3;a[5121] = 1000000 + 4;a[115] = 1000000 + 5;a[2305] = 1000000 + 6;a[99] = 1000000 + 7;a[76] = 1000000 + 8;a[423] = 1000000 + 9;a[0] = 1000000 + 1000;PrintTopK(a, n, 10);
}
int main()
{TestTopK();return 0;
}
结果演示:
(本篇完)
[ 数据结构-C实现 ] 用堆解决TopK问题相关推荐
- Java最小堆解决TopK问题
转载自 Java最小堆解决TopK问题 TopK问题是指从大量数据(源数据)中获取最大(或最小)的K个数据. TopK问题是个很常见的问题:例如学校要从全校学生中找到成绩最高的500名学生,再例如某 ...
- c语言 topk算法,scala写算法-用小根堆解决topK
topK问题是指从大量数据中获取最大(或最小)的k个数,比如从全校学生中寻找成绩最高的500名学生等等. 本问题可采用小根堆解决.思路是先把源数据中的前k个数放入堆中,然后构建堆,使其保持堆序(可以简 ...
- 建堆解决TopK问题
对于找海量的数据中最大(小)个数据的问题被称为TopK问题. 解决这个问题的方法有很多比如排序然后相应的取前K个数据,排序的算法有很多种,其中不乏时间复杂度低的,可问题很多排序算法都需要将所有数据同时 ...
- 小顶堆解决TopK问题
小顶堆解决TopK问题 这里写自定义目录标题 小顶堆解决TopK问题 问题 代码 问题 TopK问题 代码 #include <bits/stdc++.h> #define N 10 #d ...
- 《恋上数据结构第1季》二叉堆原理及实现、最小堆解决 TOP K 问题
二叉堆 BinaryHeap 堆(Heap) 堆的出现 堆简介 二叉堆(Binary Heap) 获取最大值 最大堆 - 添加 最大堆 - 添加优化 最大堆 - 删除 replace 最大堆 - 批量 ...
- 【数据结构】二叉堆、TOP K 问题
二叉堆.TOP K 问题 堆(Heap) 堆的出现,思考? 堆简介 二叉堆(Binary Heap) 获取最大值 最大堆 - 添加 最大堆 - 添加优化 最大堆 - 删除 replace 最大堆 – ...
- 教你用堆排序解决topk问题
教你用堆排序解决topk问题,同时学会堆排序. 1.什么是Top K问题? 找到数组中最大(最小)的K个数,例如7,6,3,5,2,Top3 的意思就是 找出最小的三个数即为:3,5,2. 方法1:对 ...
- 利用大顶堆实现top-k算法
有一堆二维坐标点<x1,y1>, <x2, y2>--<xn, yn>, 现在有两个问题: 给出n个坐标点,请对他们进行堆排序.坐标点的大小关系是:如果 xi> ...
- 八十四、堆排序解决TopK问题
@Author:Runsen 上次介绍了堆排序,这次介绍堆排序常见的应用场景TopK问题和. 利用堆求TopK问题 TopK问题是一个堆排序典型的应用场景. 题目是这样的:假设,我们想在大量的数据,如 ...
最新文章
- muduo之EPollPoller
- java跳出指定循环
- MyBatis 实际使用案例-typeAliases
- SAP Business Application Studio 如何同 SAP BTP CloudFoundry 环境绑定
- php自动生成mysql的触发代码。
- wxGlade的图标,原来是来自蒙德里安的名画!
- 大端模式 小端模式学习笔记
- 平衡二叉树——Balance Binary Sort Tree 设计与实现
- knife4j--api请求参数不一致问题
- apache java cache-control,Tomcat: Cache-Control
- 【C】VC6调试器的使用
- 一、为什么会产生field概念 二、MBAFF
- kafka 精准一次性
- win10系统盘清理彻底的方法
- matlab中cuk电路搭建,cuk电路matlab仿真
- 文献阅读三—Deep Text Classification Can be Fooled
- 边缘云市场份额,百度智能云领先!
- 线性表长度(线性表实训)
- 隐马尔科夫模型一(概念理解)
- 【java常见面试题】
热门文章
- 石头机器人拖地水量调节_石头扫地机器人的拖地功能鸡肋吗?
- 抓住一切机会从小事做起 优秀营销人死守的5个秘密
- 《流浪地球2》科学顾问带你“流浪月球” | 梁文杰
- 移动端自适应布局和响应式页面兼容移动端布局
- 小学计算机课题研究方案,中小学《信息技术与数学课程整合研究》课题研究方案...
- django+nginx+gunicorn+supervisord部署配置
- 通过c语言访问bmp图片文件修改图片信息
- 大道至简——浅谈机器学习分类模型选择
- Snowflake 简单介绍与使用
- oracle的commit耗时长_ORACLE COMMIT操作的详解