【数据结构初阶】--- 堆的应用:topk

news2024/10/7 18:28:03

堆的功能:topk

为什么使用topk

先举个例子,假如说全国有十万家奶茶店,我现在想找到评分前十的店铺,现在应该怎么实现?
第一想法当然是排序,由大到小排序好,前十就能拿到了。这是一种方法,但我觉得不太方便,因为我要排序就得需要数组先去存放这十万个数据,如果是100w,或是一亿个数据呢,这个时候要用4亿个字节存放这些数据,4亿个字节大概是多少内存我们来算算,1G == 1024MB == 1024*1024KB ==1024*1024*1024byte == 10亿。1G能存放10亿个字节,那么4亿个字节差不多就是400MB,你要对这些数据进行排序就需要400MB,空间的代价显而易见,很多情况下这些数据并不是在一个内存里存放着,而是在文件中,文件中的内容是存放在硬盘中的,因为硬盘空间大,而内存相比之下就很小。那么想拿到这些数据中最大的前十个,步骤也就是,将文件中的数据读取在从内存中开辟好的空间,再进行排序,找到前十个数。总而言之,直接排序会有很大的空间消耗。

什么是topk

接下来我来讲解topk是什么

  1. 把前k个数建成小堆
  2. 后面N-k个数,依次比较,如果比堆顶数据大,就替换他进堆
  3. 最后这个小堆的值就是最大的前k个

思路:

我想要在这些数据中找到前十个最大的数,那我就先向内存中开辟十个数的空间,再读取前十个数(文件中最前面的十个数),同时将这是个数构建成一个小堆,之后从文件中每读取一个数据都与堆顶元素比较,如果大于堆顶元素,就用当前读取到的数覆盖这个堆顶元素,再进行向下调整;如果小于对顶元素那就读下一个数据,一直重复到结束,最终,小堆中的是个元素就是所有数据中最大的十个数。

验证加演示如何应用

  1. 先创建一个文件“test.txt”
  2. 生成10000个小于一万的数,并且写入到文件中
void CreateNData()
{
	Heap hp;
	HeapInit(&hp);
	srand((unsigned int)time(NULL));

	char* file = "test.txt";
	FILE* pf = fopen(file, "w");
	if (pf == NULL)
	{
		perror("fopen");
		return;
	}
	for (int i = 0; i < 10000; i++)
	{
		int x = rand() % 10000;
		fprintf(pf, "%d\n", x);
	}

	fclose(pf);
}

在这里插入图片描述

  1. 打开文件,现在文件中已经有了随机生成的一万个数
    在这里插入图片描述
  2. 我们现在要找这一万个数中最大的前五个,为了清楚是哪五个数,我们手动修改五个数让它们变成最大,方便观看,我就挨着调整了5个数
    在这里插入图片描述
  3. 此时我们就要实现一个topk的功能,先建立一个大小为5的小堆,再将文件中每一个数据与堆顶元素比较,如果大于堆顶元素就取代该堆顶元素,再进行向下调整
void PrintTopk(int k)
{
	char* file = "test.txt";
	FILE* pf = fopen(file, "r");
	if (pf == NULL)
	{
		perror("fopen");
		return;
	}

	int* kminheap = (int*)malloc(sizeof(int) * 10);
	//先从文件中读取最前面的十个元素并且建立小堆
	for (int i = 0; i < k; i++)
	{
		fscanf(pf, "%d", &kminheap[i]);
		AdjustUp(kminheap, i+1);
	}
	int val = 0;
	while (!feof(pf))//读到文件尾返回非0,读到数据返回0
	{
		fscanf(pf, "%d", &val);
		if (val > kminheap[0])
		{
			kminheap[0] = val;
			AdjustDown(kminheap, k, 0);
		}
	}

	//打印堆中元素
	for (int i = 0; i < k; i++)
	{
		printf("%d ", kminheap[i]);
	}
	printf("\n");
}

在这里插入图片描述
6. 再次运行,因为刚才已经生成了数据并且我们修改了5个数据,如果再调用CreatNData()就会重新生成一万个数据覆盖掉原来的
在这里插入图片描述
好了,已经找到最大的前五个数据

如果想找最小的数据,那就建立大堆,随之,向上向下调整的代码只需更改判断父亲和孩子间大小的符号就行

时间复杂度计算·

时间复杂度计算,按照最坏的情况,那么就是,每个数与堆顶元素比较时都比堆顶元素大,因此需要交换,需要向下调整,那么最坏的情况就是每次要调整到最下层,现在堆中有5个数,3层,所以要调整两次,现在一共有N个数,大概就要调整N*2次,最大调整次数与层数有关,层数又与堆的节点数有关,层对应了节点的范围,h层对应节点数k的范围是[2(h-2)+1,2(h-1)],而调整次数是h-1,因此调整次数与节点数k有了初步地关系,调整次数==logk,一个数据调整一次是logk,所有数据调整的次数就为N*logk

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1834008.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2024 年最新 Python 基于 LangChain 框架基础案例详细教程(更新中)

LangChain 框架搭建 安装 langchain pip install langchain -i https://mirrors.aliyun.com/pypi/simple/安装 langchain-openai pip install langchain-openai -i https://mirrors.aliyun.com/pypi/simple/ChatOpenAI 配置环境变量 环境变量 OPENAI_API_KEYOpenAI API 密钥…

在IDEA 2024.1.3 (Community Edition)中创建Maven项目

本篇博客承继自博客Windows系统Maven下载安装-CSDN博客 Maven版本&#xff1a;maven-3.9.5 修改设置&#xff1a; 首先先对Idea的Maven依赖进行设置&#xff1b;打开Idea&#xff0c;选择“Costomize”&#xff0c;选择最下边的"All settings" 之后找到Maven选项&…

聚四氟乙烯离心管 四氟反应管 消解管 PTFE螺口带盖管 特氟龙试管

一、产品介绍 样品悬浮液盛放在管状试样容器中&#xff0c;在离心机的高速旋转下&#xff0c;由于巨大的离心力作用&#xff0c;使悬浮的微小颗粒 以一定的速度沉降&#xff0c;从而与溶液得以分离。这种带密封盖或压盖的管状试样容器&#xff0c;就是离心管。 PTFE离心管&…

编程精粹—— Microsoft 编写优质无错 C 程序秘诀 03:强化你的子系统

这是一本老书&#xff0c;作者 Steve Maguire 在微软工作期间写了这本书&#xff0c;英文版于 1993 年发布。2013 年推出了 20 周年纪念第二版。我们看到的标题是中译版名字&#xff0c;英文版的名字是《Writing Clean Code ─── Microsoft’s Techniques for Developing》&a…

【面试干货】常见的编译时异常(运行时异常)及其处理

【面试干货】常见的编译时异常&#xff08;运行时异常&#xff09;及其处理 1、SQLException2、IOException3、FileNotFoundException4、ClassNotFoundException5、EOFException6、总结 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 在Jav…

电能表厂家的研发能力是实力的体现

电能表厂家的研发能力无疑是其整体实力的核心体现。一个拥有强大研发能力的电能表厂家&#xff0c;不仅能够持续推出具有竞争力的新产品&#xff0c;满足市场需求&#xff0c;还能引领行业发展&#xff0c;塑造企业品牌形象。 一、研发能力对电能表厂家的重要性 研发能力是电…

图纸管理的方法、图纸管理软件

图纸管理是一个复杂且关键的过程&#xff0c;它涉及到图纸的创建、存储、共享、修改、审核、存档和检索等多个环节。以下是根据参考文章总结的图纸管理的具体内容和方法&#xff1a; 一、图纸管理的目的 1、确保图纸的准确性&#xff1a;通过规范的管理流程和质量控制措施&…

Failed to execute goal org.apache.maven.plugins:maven-antrun-plugin:1.8:

Mvan 点击执行 mvn install https://repo1.maven.org/maven2/org/apache/maven/plugins/maven-antrun-plugin/1.8/maven-antrun-plugin-1.8.pom

小米手机怎么用代理换ip:步骤详解与实用指南

在数字化时代&#xff0c;网络安全与隐私保护日益受到重视。对于小米手机用户而言&#xff0c;使用代理换IP已成为提升网络安全性、访问特定网站或绕过地域限制的有效手段。本文将详细介绍如何在小米手机上设置代理以更换IP地址&#xff0c;帮助用户更好地保护个人信息和享受更…

【NOI-题解】1448. 随机体能测试1469. 数的统计1511. 数字之和为13的整数1846. 阿尔法乘积

文章目录 一、前言二、问题问题&#xff1a;1448. 随机体能测试问题&#xff1a;1469. 数的统计问题&#xff1a;1511. 数字之和为13的整数问题&#xff1a;1846. 阿尔法乘积 三、感谢 一、前言 本章节主要对嵌套循环的题目进行讲解&#xff0c;包括《1448. 随机体能测试》《1…

Swift开发——存储属性与计算属性

Swift语言开发者建议程序设计者多用结构体开发应用程序。在Swift语言中,结构体具有了很多类的特性(除类的与继承相关的特性外),具有属性和方法,且为值类型。所谓的属性是指结构体中的变量或常量,所谓的方法是指结构体中的函数。在结构体中使用属性和方法是因为:①匹别于结…

泛微开发修炼之旅--19ecode获取用户人员信息方案汇总及代码示例(含pc端和移动端)

文章详情链接&#xff1a;19ecode获取用户人员信息方案汇总及代码示例&#xff08;含pc端和移动端&#xff09;

Android Basis - Google Keybox

什么是Keybox Keybox 又称为Gooogle attestation key&#xff0c;是Google用于管理、统计运行GMS套件设备的一种手段。 通常我们会向Google申请keybox&#xff0c;结合可能得出货量&#xff0c;提供如下信息给到的Google。 1. fingerprint 2. device id 列表 举个例子&am…

(done) AFL 都有哪些阶段? Stage progress

参考资料&#xff1a;https://afl-1.readthedocs.io/en/latest/user_guide.html 所有阶段如下&#xff0c;包括详细的解释

下载lombok.jar包,简化类的代码

Download (projectlombok.org) 去这个网站下载lombok.jar包 打开这个包文件的位置,拖到项目lib文件夹: 在这里右键添加为库(Add as library)。 添加这三个注解即可&#xff0c;类里面不需要其他东西了

基于Python的垃圾分类检测识别系统(Yolo4网络)【W8】

简介&#xff1a; 垃圾分类检测识别系统旨在利用深度学习和计算机视觉技术&#xff0c;实现对不同类别垃圾的自动识别和分类。应用环境包括Python编程语言、主流深度学习框架如TensorFlow或PyTorch&#xff0c;以及图像处理库OpenCV等&#xff0c;通过这些工具集成和优化模型&a…

物联网技术-第3章物联网感知技术-3.3传感技术

目录 1.1什么是传感器 1.1.1生活中的传感器 1.1.2人的五官与传感器 1.1.3传感器的定义 1.1.4传感器的组成 1.2传感器的特性 1.2.1传感器的静态特征 1、灵敏度&#xff08;静态灵敏度&#xff09; 2.精度 3.线性度&#xff08;非线性误差&#xff09; 4.最小检测量&a…

UITableView初识之分组显示数据Demo

基本介绍 继承自UIScrollView&#xff0c;因此可以滚动。 需要Datasource 遵循UITableViewDataSource协议的OC对象&#xff0c;都可以是UITableView的数据源&#xff0c;该协议中的方法告诉UITableView如何显示数据。 关于UITableView UITableView显示分组数据&#xff0c;对应…

【Android】使用SeekBar控制数据的滚动

项目需求 有一个文本数据比较长&#xff0c;需要在文本右侧加一个SeekBar&#xff0c;然后根据SeekBar的上下滚动来控制文本的滚动。 项目实现 我们使用TextView来显示文本&#xff0c;但是文本比较长的话&#xff0c;需要在TextView外面套一个ScrollView&#xff0c;但是我…

【 ARMv8/ARMv9 硬件加速系列 3.5.1 -- SVE 谓词寄存器有多少位?】

文章目录 SVE 谓词寄存器(predicate registers)简介SVE 谓词寄存器的位数SVE 谓词寄存器对向量寄存器的控制SVE 谓词寄存器位数计算SVE 谓词寄存器小结SVE 谓词寄存器(predicate registers)简介 ARMv9的Scalable Vector Extension (SVE) 引入了谓词寄存器(Predicate Register…