数据结构进阶篇 之 【堆的应用】(堆排序,TOP-K问题)详细讲解

在这里插入图片描述
所有人都关心我飞的高不高,只有我妈关心我翅膀硬不硬

一、堆的应用

1. 堆排序

1.1 建堆

1.2 利用堆删除思想来进行排序

2.TOP-K问题

二、完结撒❀

–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀-正文开始-❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–
学习一个知识,我们起码要直到它的用途,那样才算学会了

一、堆的应用

1.堆排序

大家肯定都学过冒泡排序,快速排序等等,在学完堆之后我们也可以用堆来实现数据排序。
(ps:冒泡排序的时间复杂度:O(N^2))

1.1 建堆

升序:建大堆
降序:建小堆

建堆方式可能与大家预想的不太一样,但确实如此,升序我们需要建大堆,降序我们建小堆,再利用堆删除的思想进行排序,时间复杂度会低很多。

1.2 利用堆删除思想来进行排序

建堆和堆删除中都用到了向下调整,因此掌握了向下调整,就可以完成堆排序
代码实现:

void Swap(HPDataType* px, HPDataType* py)
{
	HPDataType tmp = *px;
	*px = *py;
	*py = tmp;
}

//向下调整O(logN)
void AdJustDown(HPDataType* a, int n, int parent)
{
	//从左孩子开始,child为小孩子那个
	int child = parent * 2 + 1;

	while (child < n)
	{

		if (child + 1 < n && a[child] > a[child + 1])
		{
			++child;
		}

		if (a[child] < a[parent])//小堆<,大堆>
		{
			Swap(&a[parent], &a[child]);
			parent = child;
			child = child * 2 + 1;
		}
		else
		{
			break;
		}
	}
}

//升序  大堆 O(N*logN)
//降序  小堆 O(N*logN)
void HeapSort(HPDataType* a, int n)
{
	//根据数组直接建堆 O(N)
	for (int i = (n - 1 - 1) / 2; i >= 0; --i)
	{
		AdJustDown(a, n, i);
	}

	//交换根和尾的位置,再向下对前end(end每次少一个)的数进行调整 O(N*logN)
	int end = n - 1;
	while (end > 0)
	{
		Swap(&a[0], &a[end]);
		AdJustDown(a, end, 0);
		--end;
	}
}

只需要将要排序的数组地址和数组元素的总个数作为实参传过来,并且会向下调整,就可以实现排序。
这样的堆排序时间复杂赋为O(N*logN)

我们拿一个数组以降序排小堆为大家举例讲解:

int arr[] = {5,2,3,6,1,4,7}

逻辑图解:

在这里插入图片描述
因为每次向下调整,根一定是数组中最小值,将最小值与当前数组访问的尾坐标进行交换,直到end为0,数组中的元素便以排好顺序。

2.TOP-K问题

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

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

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

1. 用数据集合中前K个元素来建堆

             前k个最大的元素,则建小堆
             前k个最小的元素,则建大堆

2. 用剩余的N-K个元素依次与堆顶元素来比较,不满足则替换堆顶元素

将剩余N-K个元素依次与堆顶元素比完之后,堆中剩余的K个元素就是所求的前K个最小或者最大的元素。

为了更好的给大家讲解,我们可以现根据文件操作手动造出一些数据来

代码如下:

//造数据
void CreateNDate()
{
	int n = 10000;
	srand(time(0));
	const char* file = "data.txt";
	FILE* fin = fopen(file, "w");
	if (fin == NULL)
	{
		perror("fopen error");
		return;
	}

	for (int i = 0; i < n; ++i)
	{
		int x = rand();
		fprintf(fin, "%d\n", x);
	}

	fclose(fin);
}

以读的方式在data.txt文件中造出10000个随机数
效果如下:
在这里插入图片描述当然,如果感觉10000个数据不够多,可以手动添加更多数据。

接下来我们就在这10000个数据中进行TOp-K问题的讲解

如何在这10000个数据中选出前K个最大的数呢?

上面对TOP-K问题的讲解已经给出了思路

我们可以先看一下代码实现:

//按照大小选出前k个值
void Tokp()
{
	//选出前k个最大数据
	printf("请输入前几个最大的值:>");
	int k = 0;
	scanf("%d", &k);

	//将数据中前k个数据存入到创建的minheap数组中
	const char* file = "data.txt";
	FILE* fout = fopen(file, "r");
	if (fout == NULL)
	{
		perror("fopen error");
		return;
	}

	int* minheap = (int*)malloc(sizeof(int) * k);
	if (minheap == NULL)
	{
		perror("malloc fail");
		return;
	}

	for (int i = 0; i < k; i++)
	{
		fscanf(fout, "%d", &minheap[i]);
	}

	//建堆(向下建堆)
	for (int i = (k - 1 - 1) / 2; i >= 0; --i)
	{
		AdJustDown(minheap, k, i);
	}

	//判断大小进行替换
	int x = 0;
	while (fscanf(fout, "%d", &x) != EOF)
	{
		if (minheap[0] < x)
		{
			minheap[0] = x;
			AdJustDown(minheap, k, 0);
		}
	}

	for (int i = 0; i < k; i++)
	{
		printf("%d ", minheap[i]);
	}

	fclose(fout);

}

这里对文件操作函数比如:fscanf,fprintf等不太熟悉的同学建议去官网进行查询如何使用之后再进行Top-K问题的学习
官网网址:cplusplus

假设我们要前10个最大的数据,那么输入k为10.
实现逻辑步骤:

1.输入k为10
2.以读的方式打开data.txt文件
3.创建一个10个数据空间大小(单位为字节)的数组
4.将文件中前10个数存入到数组中
5.对数组进行向下建堆(这里我们要前10个最大的数据,所以要建小堆)
6.将根节点以此与剩余9990个数据进行对比,大于根节点就进行替换再对前十个数据进行向下调整
7.打印数组,关闭文件

因为创建的是小堆,那么根节点的值一定是堆中最小的,如果后续数据大于根节点的值,替换后再向下调整,最后对比完数据前十个建好的小堆数据就是这10000个数据中最大的10个。

调用函数打印结果:
在这里插入图片描述
因为10000个数据比较大,并且我们也并不知道这10000个数据中都有哪些数组,心里没有底
那么会不会有同学怀疑打印出的数值是否正确呢?

下面我教大家怎么检验所敲的该函数是否正确
我们可以在造数据的函数中做一些手脚
代码如下:

//造数据
void CreateNDate()
{
	int n = 100000;
	srand(time(0));
	const char* file = "data.txt";
	FILE* fin = fopen(file, "w");
	if (fin == NULL)
	{
		perror("fopen error");
		return;
	}

	for (int i = 0; i < n; ++i)
	{
		int x = (rand()+i)%10000;//检验程序准确
		fprintf(fin, "%d\n", x);
	}

	fclose(fin);
}

这次我们将造出来的随机数该成100000个(判断数据增多会不会出现BUG)
再将造出来的每一个随机数都加上i并且余上10000

因为随机数所返回的数值大小范围为30000左右,我们为了让造出来的数更加随机,就每次加上i
余上10000的目的是为了让造出来的数字都在0~9999之间

之后我们直接执行该函数

执行后打开data.txt文件夹,我们会看到100000个数值在0~9999之间的数组

我们在该文件夹中随机更改5个数字,将这5个数字都改成大于10000的值,越大越好,之后保存

再对该文件里的所有数值进行Tokp,假设输入k为10,那么最后出来结构只要包含我们所更改的5个数据,就说明该函数打印前k个最大数据是正确的。

二、完结撒❀

如果以上内容对你有帮助不妨点赞支持一下,以后还会分享更多编程知识,我们一起进步。
最后我想讲的是,据说点赞的都能找到漂亮女朋友❤
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

GPT-5:更强的ChatGPT!将在高级推理功能上实现重大进步!GPT-5有哪些功能作用?

自 Claude 3 发布以来&#xff0c;外界对 GPT-5 的期待越来越强。毕竟Claude 3已经全面超越了 GPT-4&#xff0c;成为迄今为止最强大模型。 对于即将发布的GPT-5&#xff0c;有哪些期待&#xff1f; 目前来说&#xff0c;GPT-5的将具备哪些新能力&#xff1f; GPT-5性能进步…

SA2601A 矽塔SYTATEK双NMOS半桥栅极驱动芯片 600V单相

SA2601A是一款针对于双NMOS的半桥栅极驱动芯片&#xff0c;专为高压、高速驱动N型功率MOSFET和IGBT设计&#xff0c;可在高达600V电压下工作。 SA2601A内置VCC和VBS欠压(UVLO)保护功能&#xff0c;防止功率管在过低的电压下工作&#xff0c;提高效率。 SA2601A输入脚兼容3.3-15…

安装pytorch3d 0.3.0遇到的一些问题

官网&#xff1a;PyTorch3D A library for deep learning with 3D datahttps://pytorch3d.org/最新版本pytorch3d/INSTALL.md at main facebookresearch/pytorch3d (github.com) 之前版本Releases facebookresearch/pytorch3d (github.com) 找到需要的版本&#xff0c;例如…

2024春算法训练3——数组与字符串

一、题解 1、A-[NOIP2013]记数问题_2024春算法训练3——数组与字符串 (nowcoder.com) 直接暴力用一个哈希表存每个数出现的次数&#xff0c;最坏的时间时间复杂度为7*10^7&#xff08;实际上比这个数要小&#xff09;&#xff1b;代码如下&#xff1a; #include<iostream…

SSL安全证书多少钱?

SSL安全证书多少钱&#xff1f;单域名、多域名与通配符SSL证书的全面对比与价格分析。SSL&#xff08;Secure Sockets Layer&#xff09;证书作为一种加密技术&#xff0c;能够确保网站数据传输的安全性和可靠性&#xff0c;对于提升网站信誉和保护用户隐私具有至关重要的作用。…

niushop单商户V5多店版源码分享三端uniapp打包方法包括PC端_小程序或h5端打包_收银端打包_APP端打包_商户端

目前多店版有四端uniapp&#xff0c;包括PC端uniapp&#xff0c;商家端uniapp&#xff0c;收银端uniapp&#xff0c;门店手机端uniapp&#xff0c;下面我总结下这些端的打包流程希望能帮助到大家&#xff0c;需要交流的可以看我昵称或者点我头像关注我分享代码和教程 一.niush…

kettle介绍-参数变量

ETL中为什么使用参数变量 实现ETL的复用D,Q,P环境不同,使用变量方便发布有的条件需要外部传入增量ETL灵活性强 kettle中参数变量种类 Environment VariablesKettle VariablesInternal VariablesTransformation中的变量Job中的变量 Environment Variables 通过Set Environm…

QT - 日志:qDebug/qInfo/qWarning/qCritical

篇一、日志打印函数 头文件&#xff1a; #include <QDebug> 代码&#xff1a;qDebug()<<"hello world!"; 其他打印级别&#xff1a; qInfo(): 普通信息 qDebug(): 调试信息 qWarning(): 警告信息 qCritical(): 严重错误 qFatal(): 致命错误 1. qDebug…

FSH6罗德与施瓦茨FSH6频谱分析仪

181/2461/8938产品概述&#xff1a; R&S FSH6频谱分析仪坚固耐用、方便易用&#xff0c;专为野外使用而设计。它重量轻、操作简单、设计合理且具有大量测量功能&#xff0c;是任何需要高效测量仪器进行户外工作的人不可或缺的工具。 R&S FSH6是一款手持式频谱分析仪&…

Jupyter Notebook启动及其常用快捷键

添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 1.JupyterNotebook 第一种启动方式 点击 windows 电脑左下角开始 > 搜索 Anaconda > 点击 Anaconda Prompt 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 在命令行窗口输入&…

华盛顿大学撰文反驳微软,我们无法删除大模型关于哈利波特的记忆

在人工智能的发展过程中&#xff0c;一个引人入胜的议题是机器学习模型是否能够被训练以忘记其曾经学到的信息。近期&#xff0c;Ronen Eldan和Mark Russinovich在其研究“谁才是哈利波特&#xff1f;”[1]中提出了一种创新技术&#xff0c;声称能够从LLMs中“抹去”特定数据集…

城市交通视频视频联网系统实施方案

目录 1.需求调研 2.系统设计 3.技术分析 4.技术开发 5.系统平台环境要求 6.网络要求 7.安全要求 8.项目交付和验收 8.1交付准备 8.2系统安装、培训 8.2.1系统验收 8.2.2项目进度计划 附录&#xff1a;交通监控设备情况调研表 1.需求调研 从SZ市交通运输局、以及下…

opencv使用问题记录一二

opencv介绍 opencv是一个计算机视觉处理软件库&#xff0c;拥有强大的功能和高效的性能。 但是由于早期版本的原因&#xff0c;存在一些与目前主流使用不兼容的问题 问题与解决 RGB通道顺序 一般图片处理类库的通道顺序就是RGB&#xff0c;但是opencv的是反过来的&#xf…

如何改写出优质文案,AI写作工具有方法

在当今数字化时代&#xff0c;内容创作已成为企业和个人在市场竞争中脱颖而出的关键因素。而写作优质文案是吸引读者注意力、传达信息以及促使行动的重要手段之一。然而&#xff0c;对许多人来说&#xff0c;写作可能是一项具有挑战性的任务。幸运的是&#xff0c;随着人工智能…

书生·浦语大模型开源体系(二)笔记

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

【Vscode】无法将“python,pip,node,npm等”识别为cmdlet...问题

问题出现场景 新换个电脑&#xff0c;然后重新安装了软件&#xff0c;又复现一次又一次“老生常谈”的问题。 解决方法 网络答案吧五花八门&#xff0c;我采取一个我的场景解决可行的方案&#xff0c; 首先我的场景是&#xff0c;环境变量&#xff0c;配置路径都是没有问题…

super关键字的使用总结

一、super关键字的使用1. 为什么需要super&#xff1f;举例1&#xff1a;子类继承父类以后&#xff0c;对父类的方法进行了重写&#xff0c;那么在子类中&#xff0c;是否还可以对父类中被重写的方法进行调用&#xff1f; 可以&#xff01;举例2&#xff1a;子类继承父类以后&a…

ice-06 运用Burp-Suite进行暴力破解(攻防世界)

ice-06 步骤一&#xff1a;点击超链接&#xff0c;发现只有报表中心才有用。 步骤二&#xff1a;点进去发现输入日期范围没有用 步骤三&#xff1a;使用Burp Suite进行抓包&#xff0c;把值传到Action到Intruder中 步骤四&#xff1a;如图所示进行配置 步骤五&#xff1a;攻击…

13.2k star, 高生产力的低代码开发平台 lowcode-engine

13.2k star, 高生产力的低代码开发平台 lowcode-engine 分类 开源分享 项目名: lowcode-engine -- 高生产力的低代码研发平台 Github 开源地址&#xff1a; GitHub - alibaba/lowcode-engine: An enterprise-class low-code technology stack with scale-out design / 一套面…

【滤波器基础】卡尔曼滤波器

滤波器基础 为了进一步抑制高频噪声&#xff0c;科研人员也会采用一些高阶低通滤波器来对电流采样信号的高频噪声进行抑制&#xff0c;常用的一种滤波器为&#xff1a;巴特沃兹滤波器。除了这种滤波器&#xff0c;也存在如贝塞尔、切比雪夫滤波器等。 巴特沃斯滤波器 在线性控…