【数据结构】如何应用堆解决海量数据的问题

在这里插入图片描述

堆(Heap数据结构堆在计算机科学中有着广泛的应用,今天来介绍两种堆的应用:堆排序、Top-k问题🍉

堆排序

​ 堆排序是一种基于堆数据结构的排序算法。它的基本思想是,将待排序的序列构建成一个大根堆(或小根堆),然后依次取出堆顶元素(即最大值或最小值),将其放入已排序序列的末尾,再将剩余的元素重新调整为一个新的堆。重复这个过程,直到所有元素都被取出并放入已排序序列中。

具体来说,堆排序的过程如下:

  1. 将待排序的长度为n序列构建成一个大根堆(或小根堆)。这个过程可以从最后一个非叶子节点开始,依次向前进行,保证每个子树都是一个大根堆(或小根堆)。
  2. 取出堆顶元素(即最大值或最小值),将其放入已排序序列的末尾。
  3. 将剩余(n-1)的元素重新调整为一个新的堆。
  4. 重复步骤 2 和步骤 3,直到所有元素都被取出并放入已排序序列中。最终得到的序列就是排好序的。

最终得到的序列就是排好序的。

堆排序的时间复杂度为 O(nlogn),空间复杂度为 O(1)。

在这里插入图片描述

向下调整法

从非叶节点的最后一个数据的下标开始,每次取出孩子中较大或较小的数(看是大堆还是小堆)向下进行调整,由于每多一层,下层是上层的二倍,这种办法直接可以省略掉最后一层,也可以达到建堆的目的,所以这种办法为更优的办法。

由于需要向下调整,所以这种办法需要找到子节点,我们已经知道父结点的运算了,子结点就是父节点的逆运算。

结合上面所说,实现代码如下:

void AdjustDown(HeapDataType* arr, int n, int parent)//向下调整
{
	assert(arr);
	int child = parent * 2 + 1;
	while (child < n)
	{
		if (child<n - 1 && arr[child] > arr[child + 1])
		{
			child = child + 1;
		}
		if (arr[child] < arr[parent])
		{
			swap(&arr[child], &arr[parent]);
		}
		parent = child;
		child = child * 2 + 1;
	}
}

void HeapSort(int* a,int n)//堆排序
{
	for (int i = (n - 2) / 2; i >= 0; i--)
	{
		AdjustDown(a, n,i);
	}

	for (int i = n-1; i > 0; i--)
	{
		swap(&a[0], &a[i]);
		AdjustDown(a, i, 0);
	}
	for (int i = 0; i < n; i++)
	{
		printf("%d ", a[i]);
	}
}

int main()
{
	int arr[] = { 1,4,6,2,4,8,5,8,3,111,4,5,32,44 };
	HeapSort(arr, sizeof(arr) / sizeof(int));
}

Top-k问题

Top-k 问题是指在一个数据集中找到前 k 个最大(或最小)的元素。一般情况下数据量都比较大。 比如:专业前10名、世界500强、富豪榜、游戏中前100的活跃玩家等。

下面是使用堆排序实现 Top-k 问题的具体步骤:

  1. 创建一个大小为 k 的小根堆,用于存储当前的前 k 个最大元素。
  2. 将前 k 个元素插入小根堆中。
  3. 遍历剩余的元素,对于每个元素执行以下操作:
    • 如果当前元素比堆顶元素大,则将堆顶元素弹出,再将当前元素插入堆中。
  4. 遍历完所有元素后,小根堆中剩余的 k 个元素就是前 k 个最大元素。

使用堆排序实现 Top-k 问题的时间复杂度为 O(nlogk),空间复杂度为 O(k),其中 n 是数据集的大小。这种方法适用于数据集较大的情况,但需要额外的空间来存储堆。

代码实现

  • 生成一个有10000随机数的文件
void CreateNDate()	//生成一个有10000个随机数的文件
{
	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() % 10000;
		fprintf(fin, "%d\n", x);
	}
	fclose(fin);
}

按上述步骤进行排序

void AdjustDown(HeapDataType* arr, int n, int parent)//向下调整
{
	assert(arr);
	int child = parent * 2 + 1;
	while (child < n)
	{
		if (child<n - 1 && arr[child] > arr[child + 1])
		{
			child = child + 1;
		}
		if (arr[child] < arr[parent])
		{
			swap(&arr[child], &arr[parent]);
		}
		parent = child;
		child = child * 2 + 1;
	}
}
void PrintTopK(int k)
{
	const char* file = "data.txt";
	FILE* fin = fopen(file, "r");
	if (fin == NULL)
	{
		perror("fopen error");
		return;
	}
	int* heap = (int*)malloc(k * sizeof(int));
	int x;
	for (int i = 0; i < 5; i++)
	{
		fscanf(fin,"%d",&heap[i] );//将前k个元素放到数组里
	}
    for (int i = (k - 1 - 1) / 2; i >= 0; i--)	//将k个元素建立一个小堆
	{
		AdjustDown(heap, k, i);
	}
	while (!feof(fin))
	{
		fscanf(fin, "%d", &x);
		if (heap[0] < x)
		{
			heap[0] = x;		//将剩余n-k个元素依次与堆顶元素交换,不满则则替换

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

int main()
{
	CreateNDate();
	PrintTopK(10);
}

img

✨本文收录于数据结构理解与实现

当你喜欢一篇文章时,点赞、收藏和关注是最好的支持方式。如果你喜欢我的文章,请不要吝啬你的支持,点赞👍、收藏⭐和关注都是对我最好的鼓励。感谢你们的支持!

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

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

相关文章

Keil 5 MDK 发律师函警告了,如何用STCubeIDE开发标准库的程序(STM32F103C8T6为例)

用STCubeIDE进行标准库开发 1、CubeIDE介绍 https://www.stmcu.com.cn/ecosystem/Cube/STM32CubeIDE 2、CubeIDE下载 点击上面的链接&#xff0c;登录即可下载 3、搭建Demo工程 新建一个工作空间 创建一个工程 选择芯片-STM32F103C8T6 填写工程信息 添加标准库到工程 标…

SSRS rdlc报表 六 报表分组和总计

报表分组和总计在报表中是一个很常用的功能&#xff0c;比如我们需要按部门进行分组&#xff0c;统计每个部门的费用支出&#xff0c;或者在进一步分组&#xff0c;每个部门每个月的费用支出&#xff0c;通过rdlc报表&#xff0c;很容易实现这个需求。 我们下面要讲解的案例&a…

mac免费杀毒软件哪个好用?如何清理mac系统需要垃圾

CleanMyMac x是一款功能强大的Mac系统优化清理工具&#xff0c;使用旨在帮助用户更加方便的清理您系统中的所有垃圾&#xff0c;从而加快电脑运行速度&#xff0c;保持最佳性能&#xff0c;更加稳定、流畅、快速&#xff01;&#xff01;&#xff01; CleanMyMac X无疑是目前m…

开放式耳机和封闭式耳机的区别有哪些?开放式耳机有哪些推荐?

开放式耳机和封闭式耳机的区别主要在以下几个方面&#xff1a; 设计结构&#xff1a;开放式耳机通常有一个开放的设计&#xff0c;不需要塞入耳即可收听音乐&#xff0c;同时与外部环境进行交互。封闭式耳机则是封闭的设计&#xff0c;耳机驱动单元之间是封闭和隔离的&#xf…

使用IIS创建WEB服务

文章目录 前言一、Web服务是什么&#xff1f;1.Web服务概述2.如何获取网页资源3.常见Web服务端软件4.什么是IIS 二、安装IIS1.安装Web服务器角色2.准备网页文件3.配置Web站点4.客户端浏览例&#xff1a;配置IIS站点 三、虚拟主机概述1.虚拟Web主机2.虚拟主机的几种类型3.基于端…

国内做校园信息化的龙头企业公司有哪些?

随着数字化转型的加速&#xff0c;越来越多的学校开始寻求校园信息化的解决方案&#xff0c;相比于传统信息化模式&#xff0c;国内有哪些做校园信息化做得比较好的企业&#xff1f;他们采用的又是什么样的方式&#xff1f; 一文带你了解&#xff0c;零代码平台搭建校园信息化…

EMC模式如何助力新能源服务商攻坚克难

01. 什么是合同能源管理&#xff1f; 合同能源管理(EMC-Energy Management Contract)是一种新型的市场化节能机制,其实质就是以减少的能源费用来支付节能项目全部成本的节能投资方式。&#xff1a;节能服务公司与用能单位以契约形式约定节能项目的节能目标&#xff0c;节能服务…

算法设计与分析期末总结

0000前言&#xff1a;基本是为了我自己看的一些我容易忘记的东西&#xff0c;为考试作准备把&#xff0c;主要使后半部分的知识&#xff0c;前半部分请看算法设计与分析阶段考总结 第五章 回溯算法是一种系统地搜索问题的解的方法。某个问题的所有可能解的称为问题的解空间&…

华为OD机试真题 Java 实现【寻找相似单词】【2023Q2 200分】

一、题目描述 给定一个可存储若干单词的字典&#xff0c;找出指定单词的所有相似单词&#xff0c;并且按照单词名称从小到大排序输出。 单词仅包括字母&#xff0c;但可能大小写并存&#xff08;大写不一定只出现在首字母&#xff09;。 相似单词说明&#xff1a; 给定一个…

北京君正应用案例:双镜头双画面乔安枪球联动摄像头

你是否遇到过这种问题&#xff1f; 既要看店铺又要看柜台 既要看车又要看大门 雷龙发展提供原厂技术支持&#xff0c;并提供君正集成电路完整解决方案&#xff0c;大大降低你的开发难度及开发时间。 单镜头摄像头一台不够广 出现监控盲区&#xff0c;让小偷有可趁之机 只能装两…

linuxOPS基础_Linux文件管理

Linux下文件命名规则 可以使用哪些字符&#xff1f; 理论上除了字符“/”之外&#xff0c;所有的字符都可以使用&#xff0c;但是要注意&#xff0c;在目录名或文件名中&#xff0c;不建议使用某些特殊字符&#xff0c;例如&#xff0c; <、>、&#xff1f;、* 等&…

Nacos、Eureka和Zookeeper有什么区别

Nacos、Eureka和Zookeeper都是服务注册中心&#xff0c;它们的主要功能是管理分布式系统中各个微服务实例的注册与发现。它们之间的主要区别在于&#xff1a; 1. 语言支持&#xff1a;Nacos是用Java语言开发的&#xff0c;Eureka是用Java语言开发的&#xff0c;Zookeeper则是用…

开源项目ChatGPT-website再次更新,累计下载使用1600+

&#x1f4cb; 个人简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是阿牛&#xff0c;全栈领域优质创作者。&#x1f61c;&#x1f4dd; 个人主页&#xff1a;馆主阿牛&#x1f525;&#x1f389; 支持我&#xff1a;点赞&#x1f44d;收藏⭐️留言&#x1f4d…

【数组的深刻理解】

#include<stdio.h> #define N 10 int main() {int a[N] { 0 }; //定义并初始化数组return 0; } 概念&#xff1a;数组是具有相同数据类型的集合。 数组的内存布局 #include<stdio.h> int main() {int a 10;int b 20;int c 30;printf("%p\n", &a…

一文带你了解MySQL之optimizer trace神器的功效

前言&#xff1a; 对于MySQL 5.6以及之前的版本来说&#xff0c;查询优化器就像是一个黑盒子一样&#xff0c;你只能通过EXPLAIN语句查看到最后优化器决定使用的执行计划&#xff0c;却无法知道它为什么做这个决策。这对于一部分喜欢刨根问底的小伙伴来说简直是灾难&#xff1…

基于ARIMA-LSTM组合模型的预测方法研究(Python代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

招投标系统简介 招投标系统源码 java招投标系统 招投标系统功能设计

项目说明 随着公司的快速发展&#xff0c;企业人员和经营规模不断壮大&#xff0c;公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境&#xff0c;最大限度控制采购成本至关重要。符合国家电子招投标法律法规及相关规范&#xff0c;以及…

如何使用wireShark的追踪流功能抓取并还原文件

简介 WireShark的追踪流功能可以帮我们抓取从网络上下载的各种文件&#xff0c;接下来就演示下如何抓取并且进行还原。 使用Nginx搭建文件存储服务器 只要是通过http网站下载的包&#xff0c;都可以通过追踪流工具进行抓取。这里为了演示&#xff0c;临时搭建一个Nginx文件存…

spring(不是springboot)集成apllo方案

现在到处都是基于 springboot 的微服务项目。 不巧手头碰到了一个 spring 的项目&#xff0c;打war包直接放到tomcat中启动的。 现在要将apollo集成进来&#xff0c;要求 Access Key 不可以放在properties 配置文件中&#xff0c;要统一使用apollo来管理。 步骤如下&#xff1a…

Goby 漏洞更新 |中保無限Modem Configuration Interface 默认口令漏洞

漏洞名称&#xff1a;中保無限Modem Configuration Interface 默认口令漏洞 English Name&#xff1a;Gemtek Modem Configuration Interface Default password vulnerability CVSS core: 5.0 影响资产数&#xff1a;4521 漏洞描述&#xff1a; Modem Configuration Inter…