【堆的应用--C语言版】

news2024/9/20 16:26:11

前面一节我们都已将堆的结构(顺序存储)已经实现,对树的相关概念以及知识做了一定的了解。其中我们在实现删除操作和插入操作的时候,我们还同时实现了建大堆(小堆)的向上(下)调整算法

在这里我们需要补充:

       我们上一节实现的算法中的向上调整算法的时间复杂度为O(n*log n),而向下调整算的时间复杂度为O(n)。所以我们就可以知道,在建堆的时候尽量选择时间复杂度较小的向下调整算法

一.堆排序

小Tip:排升序,建大堆;排升序,建小堆。

1.版本一:

基于已有数组进行建堆,取堆顶元素完成排序。

注:该版本有一个前提,必须提供现有的数据结构堆。

//1.需要堆的数据结构
//2.空间复杂度 O(N)
void HeapSort(int* a, int n)
{
	HP hp;  //创建一个堆
	for (int i = 0; i < n; i++)
	{
		HPPush(&hp, a[i]);  //将数组中每一个元素逐个插入堆中
	}
	//逐个取堆顶的元素
	int i = 0;
	while (!HPEmpty(&hp))
	{
		a[i++] = HPTop(&hp);//取堆顶的元素
		HPPop(&hp);//出堆
	}
	//销毁堆
	HPDestroy(&hp);
}

 基于前面我们已经实现过堆的顺序存储结构,在这里我们就只实现局部代码。实现思路我在代码的旁边已经进行了标注。


2.版本二:

数组进行建堆,首尾交换,交换之后的堆尾从堆中删除掉,将堆顶数据向下调整选出次大的数据。

void HeapSort(int* a, i int n)
{
	//先进行向下调整算法建堆
	for (int i = (n - 1 - 1) / 2; i >= 0; i--)
	{
		AdjustDown(arr, i, n);
	}
	//循环 将堆顶数据进行交换,交换完将调整堆(堆中的要访问的底层数组的下标减1,在进行堆的调整的时候end还是 要调整的 堆中的元素个数)
	int end = end - 1;
	while (end)
	{
		Swap(&a[0], &a[end]);
		AdustDwon(a, 0, end);
		end--;
	}
}

实现思路已经在上面的代码中已经标注了。

二 .top-k问题

          如果我们要在10个数据中,找前面3个最大的数据是多少,咋找? 如果我们要在100个数据中,找前面3个最大的数据是多少,咋找? 如果我们要在1000个数据中,找前面3个最大的数据是多少咋找? ……如果我们要在100000000000000000个数据中,找前面3个最大的数据是多少,咋找呢?

        对于数据量少的,我们可以用前面所学的打擂台,冒泡排序,选择法排序,快速排序以及上面所讲的堆排序。但是对于数据量特别大的呢,我们如果还用上面所说的方法,那就太慢太麻烦了。现在我们所玩的游戏(有很多玩家)中找积分最多的前几个玩家?世界人口中找年龄最大的人?……用上面的方法是不是就很繁琐了

        所以对于这种类似的问题结合堆的性质我们就Top-k来进行排序。Top-k问题:即就是求数据集合中前k个最大或者最小的元素,一般情况下数据量都比较大。

#include <stdio.h>
#include <stdlib.h>
void Swap(int* x, int * y)
{
	int temp = *x;
	*x = *y;
	*y = temp;
}//可不用,见后面
void AdjustDown(int* arr, int parent, int size)
{
	int child = parent * 2 + 1;//左孩子
	while (child < size)   //注意这里的条件
	{
		//找左右孩子中值最小的  小堆用>  大堆用<
		if (child + 1 < size && arr[child] > arr[child + 1])
		{
			child++;
		}
		//小堆用<  大堆用>
		if (arr[child] < arr[parent])
		{
			Swap(&arr[child], &arr[parent]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
			break;
		}
	}

}

//top-K 问题   求最大
void topk()
{
	int k = 0;
	printf("请你输入K>:");
	scanf("%d", &k);

	//以只读的方式打开文件
	const char *file = "data.txt";
	FILE* fout = fopen(file, "r");
	if (fout == NULL)
	{
		perror("fopen fail!");
		exit(1);
	}

	
	//用动态内存内存的知识,申请k个整形单位的数组
	int* minHeap = (int*)malloc(sizeof(int) * k);
	if (minHeap == NULL)
	{
		perror("malloc fail!");
		exit(2);
	}
	//从文件中读取数据
	for (int i = 0; i < k; i++)
	{
		fscanf(fout, "%d", &minHeap[i]);
	}


	//取随机生成前k个数字进行建堆  利用向下调整算法进行建堆
	for (int  i = (k-1-1)/2; i >= 0; i--)
	{
		AdjustDown(minHeap, i, k);   //建小堆
	}

	//将文件中剩余的数字和堆中的k个数据进行逐个比较,大的数字王进走,小的数字往出走
	int x = 0;
	while (fscanf(fout, "%d", &x)!=EOF)
	{
		//如果此时读取到的数据大于堆顶数据,就将
		if (x > minHeap[0])
		{
			minHeap[0] = x;   //此处也可以用Swap函数进行数据的交换
			AdjustDown(minHeap, 0, k);
		}
	}
	for (int i = 0; i < k; i++)
	{
		printf("%d ", minHeap[i]);
	}
	fclose(fout);
}

//先生成随机数字放在文件中
void CreatData()
{
	int n = 100000;
	srand((unsigned int)time(NULL));//利用时间戳进行堆随机数种子进行改变

	//以写的形式创建文件
	const char *file = "data.txt";
	FILE* fin = fopen(file, "w");
	if (fin == NULL)
	{
		perror("fin fail!");
		return;
	}

	//向文件中写入用fprintf,向文件中写入数字
	for (int i = 0; i < n; i++)
	{
		int x = (rand() + i) % 1000000;
		fprintf(fin, "%d\n", x);
	}
	fclose(fin);
}
int main()
{
	CreatData();
	topk();
	return 0;
}

实现的思路:

先实现自定义数据交换函数,向下调整算法(时间复杂度低,所以选择它),生成随机数的函数。

其次就是实现Top-K问题的核心了,先定义可以自定可在所有数字要找最大的k个数字的变量k,然后再以读的形式打开所生成随机数的那个文件,再就是开辟k个数据大小的数组空间。

然后先将文件中前k个数据存储在该数组中,再进行将数组中的k个元素进行建堆处理(此处建的是小堆)。随后循环读取文件中剩余的数据(直到遇到文件结束的标志),每一次将从文件中读取中的数据和小堆的堆顶进行比较大小,如果比堆顶数据大就将该值堆顶位置(或者交换)。于此同时之后每次还得数据调整(一直保持小堆)。读取完比较调整完之后,将最终数组中的数据打印在终端上。最终需要关闭文件哦!!!

注:

   对于Top-k 问题如果求前K个最大的数据,就建小堆,反之就建小堆。   

 》》   》》》》》》》》》 今天分享的内容就结束了,下篇见》》》》》》》》》》》》》》》

关注博主,优质内容不断更新!!!

如有错误,还望指出!

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

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

相关文章

【CSS in Depth 2 精译_024】4.2 弹性子元素的大小

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 第一章 层叠、优先级与继承&#xff08;已完结&#xff09; 1.1 层叠1.2 继承1.3 特殊值1.4 简写属性1.5 CSS 渐进式增强技术1.6 本章小结 第二章 相对单位&#xff08;已完结&#xff09; 2.1 相对…

PyInstaller问题解决 onnxruntime-gpu 使用GPU和CUDA加速模型推理

前言 在模型推理时&#xff0c;需要使用GPU加速&#xff0c;相关的CUDA和CUDNN安装好后&#xff0c;通过onnxruntime-gpu实现。 直接运行python程序是正常使用GPU的&#xff0c;如果使用PyInstaller将.py文件打包为.exe&#xff0c;发现只能使用CPU推理了。 本文分析这个问题…

TL-Tomcat中长连接的底层源码原理实现

长连接&#xff1a;浏览器告诉tomcat不要将请求关掉。 如果不是长连接&#xff0c;tomcat响应后会告诉浏览器把这个连接关掉。 tomcat中有一个缓冲区 如果发送大批量数据后 又不处理 那么会堆积缓冲区 后面的请求会越来越慢。

Java架构师未来篇大模型

目录 1. 大模型的定义2 大模型相关概念区分3 大模型的发展历程4. 大模型的特点5 大模型的分类6 大模型的泛化与微调7 大模型岗位需求8 理解大模型8.1 生活中的比喻8.2 大模型的定义9 大模型工作9.1 数据的积累9.2 模型的训练9.3 预测和应用10 大模型的实际应用10.1 语言处理10.…

240907-Gradio插入Mermaid流程图并自适应浏览器高度

A. 最终效果 B. 示例代码 import gradio as grmermaid_code """ <iframe srcdoc <!DOCTYPE html> <html><head><meta charset"utf-8" /><meta name"viewport" content"widthdevice-width" />…

C++初阶:STL详解(一)——string类

✨✨小新课堂开课了&#xff0c;欢迎欢迎~✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;C&#xff1a;由浅入深篇 小新的主页&#xff1a;编程版小新-CSDN博客 1.为什么会有string类 C 语言中&#xff0c…

Nodejs中使用Minio

Minio 安装Minio MinIO下载 下载完&#xff0c;服务端和客户端后&#xff0c;最好像我这样做&#xff0c;去分一下路径。 安装完后&#xff0c;进入bin目录输入以下指令&#xff1a; # 设置账户 setx MINIO_ROOT_USER admin# 设置密码 setx MINIO_ROOT_PASSWORD password# …

高效办公必备!图片转PDF功能,让工作更轻松

在数字化时代&#xff0c;将图片转换为PDF格式是一项非常实用的技能&#xff1b;无论是在工作、学习还是生活中&#xff0c;我们都可能遇到需要将图片转化为PDF格式的情况&#xff1b;今天通过这篇文章给大家分享四款好用的图片转pdf 的工具&#xff1a; 第一款&#xff1a;福…

flutter开发实战-flutter web加载html及HtmlElementView的使用

flutter开发实战-flutter web加载html及HtmlElementView的web控件 HtmlElementView 是 Flutter 中用于嵌入 HTML 内容的 widget。这个 widget 允许你将一个 HTML 元素嵌入到 Flutter 应用中。 一、HtmlElementView基本使用 在工程的pubspec.yaml中引入插件 HtmlElementView…

多波束EM2040D以及POSMV使用记录

多波束EM2040D采集软件SIS4.3升级到SIS5.11之后&#xff0c;我们碰到了很多问题&#xff0c;现在将问题和解决过程记录一下。 1、SIS5软件打不开 SIS5软件打不开&#xff0c;报KSlSMainApp has stopped working弹框。 ​ 判断是电脑问题&#xff0c;更新最新win10系统&#…

ue5 伤害插件

主角或敌人都能用的插件&#xff0c;复用性很高 首先创建以下插件、接口、类型文件 两个枚举中的参数名称&#xff0c;E_DamageResponse区分是各个伤害后的反应&#xff0c;比如不同伤害造成的动画或粒子特效等的不同&#xff0c;E_DamageType是伤害类型&#xff0c;有各种伤害…

【网络安全】空字节绕过:URL回调+XSS+SQL绕WAF

未经许可,不得转载。 文章目录 空字节URL回调XSSSQL空字节 \0,也称为null字节,是一个值为零的特殊字符。在编程中,通常用来表示字符串的结束。攻击者可以利用null字节注入来绕过一些验证或过滤机制。 以下三个漏洞,空字节功不可没。 URL回调 密码重置功能,发起请求后…

【牛站 / USACO2007】

题目 思路 离散化&#xff08;降低空间复杂度&#xff09; 点的编号 ∈ [ 1 , 1000 ] &#xff0c;但是点的个数最多为 2 ⋅ T ∈ [ 4 , 200 ] 点的编号 \in [1, 1000]&#xff0c;但是点的个数最多为 2 \cdot T \in[4, 200] 点的编号∈[1,1000]&#xff0c;但是点的个数最多为…

【NLP】大模型长文本处理技术与GLM-4-Plus评测

本文将介绍Transformer模型在处理长文本数据时所采用的关键技术&#xff0c;特别是旋转位置编码&#xff08;RoPE&#xff09;和Flash Attention机制。 此外&#xff0c;本文介绍GLM系列模型&#xff0c;特别是最新发布的GLM-4-Plus模型。我们将通过实际的评测方法和结果&…

管理学习(一)马云《赢在中国》创业演讲整理

目录 一、小公司也需要制度二、不要害怕冒险三、创业者要的不是技术&#xff0c;而是胆识四、不要惧怕和大企业竞争五、理念不一样&#xff0c;老板永远是对的六、要真实地为客户创造价值七、跟风险投资谈判&#xff0c;说到要做到八、风险投资&#xff0c;只能帮你不能救你九、…

24秋开学考

文件上传 上传一个.php的格式&#xff0c;上面说是非法的文件格式。 2.传了一个phpinfo.gif&#xff0c;说什么在目录里。 3.有两个页面一个labs1一个labs2 &#xff0c;当在第一个页面上传1.jpg&#xff0c;在第二个页面上传1.jpg时&#xff0c;给了我们一个目录,在测试其他时…

[图解]识别类和属性-投资少见效快产量高

1 00:00:00,530 --> 00:00:04,360 接下来&#xff0c;我们就要来识别实体类和属性了 2 00:00:05,670 --> 00:00:07,260 前面也讲了&#xff0c;从哪里识别 3 00:00:08,120 --> 00:00:11,470 从用例规约那里来识别 4 00:00:12,400 --> 00:00:15,770 在识别的时候…

气膜体育馆投资前景广阔:健康产业中的新兴机遇—轻空间

气膜体育馆作为一种新型的建筑形式&#xff0c;为投资者带来了丰富的商业机会。随着全民健身的理念普及&#xff0c;气膜体育馆在市场上逐渐展现出巨大潜力。 市场需求不断增长 随着健康意识提升&#xff0c;人们对运动场地的需求日益增加。气膜体育馆凭借其灵活的建筑形式&…

【线性代数】正定矩阵,二次型函数

本文主要介绍正定矩阵&#xff0c;二次型函数&#xff0c;及其相关的解析证明过程和各个过程的可视化几何解释&#xff08;深蓝色字体&#xff09;。 非常喜欢清华大学张颢老师说过的一段话&#xff1a;如果你不能用可视化的方式看到事情的结果&#xff0c;那么你就很难对这个…

select、poll、epoll的区别

select、poll、epoll均为linux中的多路复用技术。3种技术出现的顺序是select、poll、epoll&#xff0c;3个版本反应了多路复用技术的迭代过程。我们现在开发网络应用时&#xff0c; 一般都会使用多路复用&#xff0c;很少有用一个线程来监听一个fd的&#xff0c;其中epoll又是最…