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的活跃玩家等。

对于 Top-K 问题,能想到的最简单直接的方式就是排序,但是:如果数据量非常大,排序就不太可取了 ( 可能数据都不能一下子全部加载到内存中) 。最佳的方式就是用堆来解决,基本思路如下:

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问题相关推荐

  1. Java最小堆解决TopK问题

    转载自  Java最小堆解决TopK问题 TopK问题是指从大量数据(源数据)中获取最大(或最小)的K个数据. TopK问题是个很常见的问题:例如学校要从全校学生中找到成绩最高的500名学生,再例如某 ...

  2. c语言 topk算法,scala写算法-用小根堆解决topK

    topK问题是指从大量数据中获取最大(或最小)的k个数,比如从全校学生中寻找成绩最高的500名学生等等. 本问题可采用小根堆解决.思路是先把源数据中的前k个数放入堆中,然后构建堆,使其保持堆序(可以简 ...

  3. 建堆解决TopK问题

    对于找海量的数据中最大(小)个数据的问题被称为TopK问题. 解决这个问题的方法有很多比如排序然后相应的取前K个数据,排序的算法有很多种,其中不乏时间复杂度低的,可问题很多排序算法都需要将所有数据同时 ...

  4. 小顶堆解决TopK问题

    小顶堆解决TopK问题 这里写自定义目录标题 小顶堆解决TopK问题 问题 代码 问题 TopK问题 代码 #include <bits/stdc++.h> #define N 10 #d ...

  5. 《恋上数据结构第1季》二叉堆原理及实现、最小堆解决 TOP K 问题

    二叉堆 BinaryHeap 堆(Heap) 堆的出现 堆简介 二叉堆(Binary Heap) 获取最大值 最大堆 - 添加 最大堆 - 添加优化 最大堆 - 删除 replace 最大堆 - 批量 ...

  6. 【数据结构】二叉堆、TOP K 问题

    二叉堆.TOP K 问题 堆(Heap) 堆的出现,思考? 堆简介 二叉堆(Binary Heap) 获取最大值 最大堆 - 添加 最大堆 - 添加优化 最大堆 - 删除 replace 最大堆 – ...

  7. 教你用堆排序解决topk问题

    教你用堆排序解决topk问题,同时学会堆排序. 1.什么是Top K问题? 找到数组中最大(最小)的K个数,例如7,6,3,5,2,Top3 的意思就是 找出最小的三个数即为:3,5,2. 方法1:对 ...

  8. 利用大顶堆实现top-k算法

    有一堆二维坐标点<x1,y1>, <x2, y2>--<xn, yn>, 现在有两个问题: 给出n个坐标点,请对他们进行堆排序.坐标点的大小关系是:如果 xi> ...

  9. 八十四、堆排序解决TopK问题

    @Author:Runsen 上次介绍了堆排序,这次介绍堆排序常见的应用场景TopK问题和. 利用堆求TopK问题 TopK问题是一个堆排序典型的应用场景. 题目是这样的:假设,我们想在大量的数据,如 ...

最新文章

  1. muduo之EPollPoller
  2. java跳出指定循环
  3. MyBatis 实际使用案例-typeAliases
  4. SAP Business Application Studio 如何同 SAP BTP CloudFoundry 环境绑定
  5. php自动生成mysql的触发代码。
  6. wxGlade的图标,原来是来自蒙德里安的名画!
  7. 大端模式 小端模式学习笔记
  8. 平衡二叉树——Balance Binary Sort Tree 设计与实现
  9. knife4j--api请求参数不一致问题
  10. apache java cache-control,Tomcat: Cache-Control
  11. 【C】VC6调试器的使用
  12. 一、为什么会产生field概念 二、MBAFF
  13. kafka 精准一次性
  14. win10系统盘清理彻底的方法
  15. matlab中cuk电路搭建,cuk电路matlab仿真
  16. 文献阅读三—Deep Text Classification Can be Fooled
  17. 边缘云市场份额,百度智能云领先!
  18. 线性表长度(线性表实训)
  19. 隐马尔科夫模型一(概念理解)
  20. 【java常见面试题】

热门文章

  1. 石头机器人拖地水量调节_石头扫地机器人的拖地功能鸡肋吗?
  2. 抓住一切机会从小事做起 优秀营销人死守的5个秘密
  3. 《流浪地球2》科学顾问带你“流浪月球” | 梁文杰
  4. 移动端自适应布局和响应式页面兼容移动端布局
  5. 小学计算机课题研究方案,中小学《信息技术与数学课程整合研究》课题研究方案...
  6. django+nginx+gunicorn+supervisord部署配置
  7. 通过c语言访问bmp图片文件修改图片信息
  8. 大道至简——浅谈机器学习分类模型选择
  9. Snowflake 简单介绍与使用
  10. oracle的commit耗时长_ORACLE COMMIT操作的详解