【算法篇】利用堆高效解决大数据量时TOP-K问题
创始人
2024-03-23 06:29:28

Top-k问题

  • 1.问题描述
  • 2.分析问题
  • 3.思路
  • 4.复杂度分析
  • 5.代码实现
  • 6.总结

堆相关博客: 堆

1.问题描述

TOP-K问题:即求数据结合中前K个最大的元素或者最小的元素,一般情况下数据量都比较大。

比如:专业前10名、世界500强、富豪榜、游戏中前100的活跃玩家等。

2.分析问题

最简单的方法就是排序,先排好序再取前k个数。
或者建立一个堆,存放所有的数据元素,依次弹出堆顶元素即可
但是这两种方法在数据量非常大时是不可取的
如果我们要排的是一个文件中的数据,如果数据非常多的话,可能数据都不能一下子加载到内存当中,所以我们要换一种思路,能不能每次让加载到内存中的数据量少一点,但又不影响我们的最终的要求。

3.思路

  1. 用数据集合中前K个元素来建堆
    前k个最大的元素,则建小堆
    前k个最小的元素,则建大堆
  2. 用剩余的N-K个元素依次与堆顶元素来比较,不满足则替换堆顶元素
    将剩余N-K个元素依次与堆顶元素比完之后,堆中剩余的K个元素就是所求的前K个最小或者最大的元素。

我们要求前k个最大元素,就建小堆。
原因是:一开始把数据中前k个数放进了我们建的堆,我们把它建成小堆的话,最顶部的元素一定是这个堆里面最小的数,然后依次拿N-K个元素与堆顶比较比堆顶元素大的数就进来,然后因为我们是小堆,所以这个数会向下调整原来堆中第二小的数到顶部,然后继续拿数据与堆顶比较,满足条件就进来,进来后就调整,这样一直下去直到结束,就是前数据中前k个最大的元素。

要求前k个最小的元素,则建大堆,与上同理。

4.复杂度分析

1.时间复杂度 O(N * log2K)

首先是选K个数放进堆,然后最坏情况下是每次都调整,就是(N-K)*log2K
K + (N - K) * log2K可以近似成 N * log2K

2.空间复杂度O(K)

5.代码实现

我们的data.txt文件数据是
在这里插入图片描述
在这里我们给的数据量很小来测试。

#include 
void swap(int* n1, int* n2)
{int tmp = *n1;*n1 = *n2;*n2 = tmp;
}
void down(data_type* a, int len, int parent) //向下调整
{int child = (parent * 2) + 1; // 先假设左孩子最大while (child < len){//这里加1可能会有越界问题,可能会访问到随机值,导致出错,判断一下if (child + 1 < len && a[child + 1] < a[child]) // 如果右孩子大的话就 child++{child++;}if (a[parent] > a[child])//建立小根堆{swap(&a[parent], &a[child]);parent = child;child = (parent * 2) + 1;}else{break;}}
}
void test1()
{int minHeap[5];//建立一个堆,大小为5FILE* fout = fopen("data.txt", "r");//文件操作if (fout == NULL)//养成好习惯判断是否打开文件成功{perror("fopen");return;}int k = 5;//这里我们假设要求前5大的数for (int i = 0; i < k; i++){fscanf(fout, "%d", &minHeap[i]);//先往堆里读入前K个数}for (int i = (k - 1 - 1) / 2; i >= 0; i--)//建堆算法,不了解的可以看看文章开头提到的博客{down(minHeap, k, i);//}int val = 0;while (fscanf(fout, "%d", &val) != EOF)//继续读入N-K个数据,满足条件就进堆,进堆后进行调整。{if (val > minHeap[0]){minHeap[0] = val;down(minHeap, k, 0);}}for (int i = 0; i < k; i++){printf("%d ", minHeap[i]);//打印前5大的数//77 777 999 9999 10000}fclose(fout);//养成好习惯fclose()
}
int main()
{test1();return 0;
}

6.总结

这里的优化避免我们需要排序文件中的数据时,文件中的数据量如果过大,一下子不能加载进来的情况(因为文件在磁盘,而我们的数组元素在内存。比如文件中有100亿个整数,内存大小就是40G,非常大),所以我们一个一个读入,避免了这种情况的发生。

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...