TopK问题

gitee上有更详尽的代码:堆 + TopK代码


文章目录

  • TopK问题
    • 一、问题分析
      • 1. 方法一
      • 2. 方法二
      • 3. 方法三
    • 二、TopK实现
      • 1. 前k个数的小堆
      • 2. n-k个数和根去比较
      • 3. 打印堆
    • 三、测试

topk问题就是取n个数据中,找出最大/最小前k个数

一、问题分析

1. 方法一

n个数据进行排序,再取出前k个元素

  • 时间复杂度:O(N * logN)

2. 方法二

n个数据依次插入大堆,然后pop堆的根 k 次

  • 时间复杂度:O(N + k * logN)

设有n个数据,有log2(n + 1)层,最坏的情况就是每个数据要向上调整k次


3. 方法三

如果n很大,内存中无法储存,插入堆和排序的方法都不行

  • 用前K个数建立一个K个数的小堆

  • 剩下的N-K个数,依次跟堆顶的数据进行比较如果比堆顶数据大,就替换堆顶的数据,再向下调整

  • 最后堆里面K个数就是最大的K个数

原理:

在方法二的基础上,大堆实现不了,但小堆却能很好的实现

小堆的优点就是,根是堆中所有元素中最小的元素,我们建立一个小堆,可以存放k个数,后面n-k个数字再与之比较,这样就能把小数pop出来,把大数push进去

可能会担心:

  • 如果小堆里正好都是我们想要的数怎么办?

    那与之比较的n-k的数肯定没有比根更大的数了

  • 如果这里小堆换成大堆?

    那可能根是最大的数字,没法操作了。小的话放进去,那如果不是前k个大的数字就进去了,乱套了

时间复杂度:O(k + (n-k)*logk)


二、TopK实现

本篇在上一章:【数据结构】堆_Rinne’s blog-CSDN博客

写了几个二叉树常用的插口

gitee上有更详尽的代码:堆 + TopK代码

1. 前k个数的小堆

//定义和初始化堆
Heap hp;
HeapInit(&hp);int i = 0;
//k个数的小堆
for (i = 0; i < k; i++)
{//插入k个数据HeapPush(&hp, a[i]);
}

2. n-k个数和根去比较

比它大,替换

向下调整

//k - n 个数与根作对比
for (i = k; i < n; i++)
{if (a[i] > HeapTop(&hp)){hp.a[0] = a[i];AdjustDown(hp.a, hp.size, 0);}
}

3. 打印堆

//打印堆
void HeapPrint(Heap* hp, int n)
{int i = 0;for (i = 0; i < n; i++){printf("%d ", hp->a[i]);}printf("\n");
}

三、测试

测试代码:

这里用到了srand函数和time函数以及rand函数,用来生成随机数值

更多有关随机数生成的详细知识可以参考文章:C语言随机数生成教程

void TestTopk()
{//一共有20个数字int n = 20;int* a = (int*)malloc(sizeof(int) * n);assert(a);srand((unsigned int)time(NULL));for (int i = 0; i < n; ++i){a[i] = rand() % 10;}// 再去设置5个比10大的数a[5] = 10 + 1;a[11] = 10 + 2;a[15] = 10 + 3;a[1] = 10 + 4;a[10] = 10 + 5;PrintTopK(a, n, 5);}

测试结果:


下一篇会讲解堆排序的问题,可能感觉和topk相似,但topk只是找了前k个大的数,并没有排序

【数据结构】TopK问题相关推荐

  1. 数据结构--TopK问题

  2. 【数据结构】用堆排序解决TOPK问题

    题目名称  TOPK问题 目录 题目名称  TOPK问题 1.题目 2.题目分析 3.题目答案 4.题目知识点 4.1TOPK 4.2代码分析 推荐阅读顺序: 1.题目->3.答案->2. ...

  3. [ 数据结构-C实现 ] 用堆解决TopK问题

    TopK问题的引入:想必大家在玩王者农药的时候都遇到过xxx市第xxx韩信,xxx区第xxx赵云.或者说大家今天懒得做饭,想点个外卖,于是乎大家打开美团App,假如说想吃汉堡,大家不知道哪家汉堡好吃, ...

  4. < 数据结构 > 堆的应用 --- 堆排序和Topk问题

    目录 1.堆排序 法一:自己写堆进行排序 时间复杂度分析 法二:直接对数组建堆 ①.向上调整建堆 ②.向下调整建堆 向上建堆和向下建堆熟优? 升序能否建小堆? 排序(建大堆) 2.TopK问题 何为T ...

  5. [数据结构 -- C语言] 堆实现Top-K问题,原来王者荣耀的排名是这样实现的,又涨知识了

    目录 1.什么是Top-K问题? 1.1 Top-K基本思路 2.Top-K问题逻辑分析 2.1 建堆,大小为K的小堆 2.2 将剩余的N - K 个元素依次与堆顶元素比较,大于就替换 2.3 打印堆 ...

  6. Python 数据结构与算法——选取算法(TopK)

    该算法要解决的问题是:在线性时间内找到一个无序序列中第 kk 大的数.(或许,该程序最重要的用途是找出中间值--也就是该序列完成排序后位于中间 (1+n)/2(1+n)/2 的元素值).有趣的是,稍加 ...

  7. 【数据结构】---堆排序+TOP-K问题(了解游戏排行底层原理)

    文章目录 前言

  8. [数据结构]堆的经典——TopK问题与堆排序

    文章目录

  9. 关于某日访问次数最多的IP的topK问题的三种解法

    题目描述 在july大神的博客中,看到这样两道题: 1. 海量日志数据,提取出某日访问百度次数最多的那个IP. 2. 假设目前有一千万个记录(这些查询串的重复度比较高,虽然总数是1千万,但如果除去重复 ...

最新文章

  1. 剑指offer:字符流中第一个不重复的字符
  2. LINUX不能ping域名, 能ping ip, 添加DNS解析
  3. Java设计模式之适配器模式
  4. 高等数学:第六章 定积分的应用(2)平面曲线的弧长 做功 水压力 引力
  5. opencv进阶学习笔记14:分水岭算法 实现图像分割
  6. include指令与动作的区别【贴心,简洁】
  7. JS----面试题总结(持续更新中......)
  8. ubuntu20.04安装OPTEE
  9. 使用自动伸缩组在AWS中运行安全数据库集群
  10. 【Beam Search】seq2seq中的beam search算法过程
  11. 前端面试之 判断 true == true 需要进行哪几步操作?
  12. 使用 vsftpd 服务传输文件
  13. 计算机操作系统--文件管理
  14. java 动画 制作_DragonBones简单动画制作实例
  15. java架构师之路-并发编程
  16. 安卓APP逆向入门破解
  17. 详解去中心化代币发行机制IDO:七大平台的特性与现状 |链捕手
  18. P2504 聪明的猴子
  19. 【转载】Android 第三方ROM定制之适配谷歌Play Store
  20. python函数进阶小结_python函数的进阶

热门文章

  1. matlab中如何求两条曲线的交点并在图中标出
  2. 清华申请退学博士作品:完全用Linux工作,凸Windows
  3. 邀请别人进入队伍rust_Rust(腐蚀)怎么tp求大神指教。请写在下面
  4. Linux入门,非常适合小白
  5. 基于FPGA的USB2.0数据传输(通过本文可以自己设计USB2.0模块)
  6. wkt转shp / wkt转shapefile / shp转wkt
  7. C#把图片的白色背景转透明
  8. 计算机等级关系代数,计算机二级:关系代数运算
  9. 【文本匹配】表示型模型
  10. win7计划任务有进程无界面