【数据结构】堆主要的应用场景

news2024/11/15 13:39:15

1. 堆排序

所谓堆排序,就是在堆的基础上进行排序。

在讲解堆排序之前,让我们先来回顾一下堆的概念,

1.1 大根堆和小根堆

堆是一种完全二叉树,它有两种形式,一种是大根堆,另外一种是小根堆

    大根堆:所有的父亲结点大于或等于孩子结点。

    小根堆:所有的父亲结点小于或等于孩子结点。 

1.2 堆排序核心思想:

1. 将待排序序列构造成一个大顶堆

2. 此时整个序列的最大值就是顶堆的根节点

3. 将其与末尾元素进行交换,此时末尾就为最大值

4. 然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了。

可以看到在构建大顶堆的过程中,元素的个数逐渐减少,最后就得到一个有序序列了

1.3 堆排序步骤图解说明

假如有一个数组{4,6,8,5,9},使用堆排序,将数组升序排序

1. 假设给定无序序列结构如图所示

2.此时我们从最后一个非叶子节点开始(叶节点自然不用调整,第一个非叶子节点5/2-1=1,也就是下面的节点),从左至右,从下至上进行调整,观察6的两个子节点,从右至左,9大于6就和6互换 

3.找到第二个非叶子节点4,由于[4,9,8]中9元素最大,4和9交换

4.此时,交换导致了子根[4,5,6]结构混乱,继续调整,[4,5,6]中6最大,交换4和6

 

5.此时我们就将一个无序序列构造成了一个大顶堆。

将堆顶元素与末尾元素进行交换,使末尾元素最大,然后继续调整堆,再将堆顶元素与末尾元素交换,得到第二大元素,如此反复进行交换,重建,交换 

1.将堆顶元素9和末尾元素4进行交换

2.重新调整结构,使其继续满足堆定义

3.再将堆顶元素8与末尾元素5进行交换,得到第二大元素8 

4.后续过程,继续进行调整,交换,如此反复进行,最终使得整个序列有序

1.4 堆排序的基本思路总结

  1. 将无序序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆
  2. 将堆顶元素与末尾元素交换,将最大元素“沉”到数组末端
  3. 重新调整结构使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序

同学们可以先感受一下,后期讲到《排序》章节时会带大家实现堆排序代码的实现。

2. TOP-K问题

TOP-K问题:

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

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

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

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

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

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

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

比如:我们要实现 在随机的10000000个数据中找出前5大的数据。

(通过文件建立以及读取实现)

参考代码:

void PrintTopK(const char* filename, int k)
{
	// 1. 建堆--用a中前k个元素建堆
	FILE* fout = fopen(filename, "r");
	if (fout == NULL)
	{
		perror("fopen fail");
		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]);
	}
 
	// 前k个数建小堆
	for (int i = (k-2)/2; i >=0 ; --i)
	{
		AdjustDown(minheap, k, i);
	}
 
 
	// 2. 将剩余n-k个元素依次与堆顶元素交换,不满则则替换
	int x = 0;
	while (fscanf(fout, "%d", &x) != EOF)
	{
		if (x > minheap[0])
		{
			// 替换你进堆
			minheap[0] = x;
			AdjustDown(minheap, k, 0);
		}
	}
 
 
	for (int i = 0; i < k; i++)
	{
		printf("%d ", minheap[i]);
	}
	printf("\n");
 
	free(minheap);
	fclose(fout);
}
 
// fprintf  fscanf
 
void CreateNDate()
{
	// 造数据
	int n = 10000000;
	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) % 10000000;
		fprintf(fin, "%d\n", x);
	}
 
	fclose(fin);
}
 
int main()
{
	//CreateNDate();
	PrintTopK("data.txt", 5);
 
	return 0;
}

3. 总结

本期博客,我们讲解了堆的两个主要的应用场景,希望帮助大家更加理解堆这种特殊的完全二叉树。

希望这篇文章能给予你学习中一些帮助,如果有疑问的,欢迎在评论区与我讨论交流哦~

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

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

相关文章

2023年看过的电影和电视剧

2023年看过的电影 2023年12月21日&#xff1a;三大队 评价&#xff1a;感觉结尾不太突出&#xff0c;但是值得一看。 2023年10月02日&#xff1a;志愿军&#xff1a;雄兵出击 评价&#xff1a;感觉还行&#xff0c;场面还不错。但是记不得太多情节。 2023年08月31日&#xf…

如何将 Parallels Desktop 许可证密钥移至新的 Mac?

根据 Parallels 最终用户许可协议&#xff08;EULA&#xff09;的规定&#xff0c;您最多可以在一台设备上下载、安装和使用 Parallels Desktop 的一个原始副本。但是面对更换新机的用户&#xff0c;可以通过迁移的方式把 Parallels Desktop 许可证密钥移至新的 Mac&#xff0c…

跟《经济学人》学英文:2024年08月24日这期 What to make of America’s topsy-turvy economy

What to make of America’s topsy-turvy economy Don’t panic just yet topsy-turvy&#xff1a;颠倒的&#xff1b;混乱的&#xff1b;乱七八糟的&#xff1b; make of&#xff1a;理解&#xff1b;认为&#xff1b;看待 Make of: 这里的 “make of” 意思是如何理解或解释…

自来水厂供水监控的串口服务器应用

随着城市化进程的加快和人口的不断增长&#xff0c;自来水厂作为城市供水系统的核心组成部分&#xff0c;其稳定性和安全性对于城市的正常运行和居民的生活质量至关重要。传统的供水监控系统存在数据传输效率低、维护成本高、实时性差等问题&#xff0c;难以满足现代城市对供水…

TMDOG的微服务之路_08——使用Docker部署NestJS微服务

TMDOG的微服务之路_08——使用Docker部署NestJS微服务 博客地址&#xff1a;TMDOG的博客 在上一篇博客中&#xff0c;我们探讨了如何使用 NestJS 创建一个简单的微服务架构。为了将这些微服务部署到生产环境&#xff0c;我们可以使用 Docker 来打包和管理这些服务。本篇博客将…

Docker 数据卷的使用

Docker 数据卷的使用 文章目录 Docker 数据卷的使用导引1. 创建数据卷2. 查看创建的数据卷3. 查看数据卷的详细信息 导引 在Docker中&#xff0c;我们在创建并运行容器后&#xff0c;可以通过exec命令进入容器内部进行操作&#xff0c;但会发现一些命令是无法使用的&#xff0…

NSSCTF练习记录:[SWPUCTF 2021 新生赛]pigpig

题目&#xff1a; 根据题目名字和附件名提示&#xff0c;猜测为猪圈密码&#xff0c;对应手动解码 whenthepigwanttoeat

持久层接口开发

通常一个接口定义后&#xff0c;从持久层开始开发。 对于一个新模块需要使用工具生成模型类、mapper接口、mapper映射文件等&#xff0c;下边介绍一个工具用于自动生成代码。 1. 代码生成工具 1.1 安装插件 1.2 重启IDEA&#xff0c;连接mysql 1.3 配置代码生成规则 点击“c…

C++容器之字符串的详解

每日诗词&#xff1a; 我见青山我妩媚&#xff0c;料青山见我应如是。 ——《贺新郎甚矣吾衰矣》【宋】辛弃疾 目录 补漏&#xff1a; vector在分配新内存块后如何进行元素复制 正文&#xff1a; 字符串变量和常量 字符串变量&#xff1a; 解析&#xff1a; 字符串常量…

揭露 Sapiens:未来以人为中心的视觉任务

Sapiens | Meta Meta Reality Labs 隆重推出 Sapiens&#xff0c;这是一个尖端的模型系列&#xff0c;专为四种以人为中心的基本视觉任务而设计&#xff1a;二维姿态估计、身体部位分割、深度估计和表面法线预测。 我们的 Sapiens 模型可无缝处理 1K 高分辨率推理&#xff0c…

加州大学圣地亚哥分校 沉浸式遥操作机器人系统

想象一下&#xff0c;在VR中控制游戏角色时&#xff0c;你的手部动作能够无缝转化为角色的行动。如果将这种体验应用于现实世界中的双手机器人控制&#xff0c;将带来革命性的人机交互体验。随着Apple Vision Pro的问世&#xff0c;这一设想逐渐变为现实。然而&#xff0c;将这…

Velocity模板引擎——若依代码生成器

文章目录 快速入门准备模板数据填充运行代码 基础语法简单类型的变量获取对象类型的变量获取基础语法-循环基础语法—if判断 官网 比较擅长用于邮件&#xff0c;发票&#xff0c;web内容生成、代码生成、网页静态化 模板化的东西适合使用 当然模板引擎不止这一种&#xff0c;还…

记录|C# winform——Chart控件

目录 前言一、重点关注1.1 Chart控件效果1.2 属性1.2.0 位置讲解1.2.1 Titles——标题集合TextToolTip 1.2 .2 Series——图表序列ChartTypeLegends——图例集合 二、数据传入Chart控件2.1 如何传入数据&#xff1f;2.2 如果想限定每次展现的数据量怎么办&#xff1f; 三、标注…

主机安全-网络攻击监测

目录 概述暴力破解&#xff08;SSH爆破为例&#xff09;原理规则攻击模拟告警 端口扫描原理规则攻击模拟告警 流量劫持原理规则攻击模拟告警 参考 概述 本文介绍主机网络层面上的攻击场景&#xff0c;每种攻击场景举一个例子。监测方面以字节跳动的开源HIDS elkeid举例。 针对…

【2】搭建雅特力AT32F437ZMT OpenHarmony轻量系统开发环境

本文用于阐述如何搭建AT32F437ZMT OpenHarmony轻量系统开发环境开源组织地址&#xff1a;https://gitee.com/AT32437_OpenHarmony 1.AT-START-F437雅特力官方开发板相关资料 移植基于at32f437雅特力官方开发板AT-START-F437 AT-START-F437雅特力官方开发板相关资料 2.AT32F43…

采用不高于3次的勒让德多项式拟合原函数

利用勒让德多项式进行拟合的区域是[-1,1]&#xff0c;如果不是这个区域&#xff0c;比如是[a,b]&#xff0c;利用转化到[-1,1]。 参考以下例题计算系数 C语言代码如下 //用三阶的勒让德多项式进行拟合 #include<math.h> #include<stdio.h> #include "main.c…

智能控制,高效节能。ZLG致远电子能源智慧管理解决方案

面对楼宇及建筑群能源管理与设备控制的复杂需求&#xff0c;ZLG致远电子推出了一套能源智慧管理解决方案。该方案集设备管理、任务调度和数据可视化于一体&#xff0c;不仅实现数据的实时监控与分析&#xff0c;还助力系统节能降耗。 ZLG致远电子能源智慧管理解决方案 在ZLG致…

shallowReactive 与 shallowRef

除了之前的 ref与reactive 之外&#xff0c;Vue3 还准备了另外两个API&#xff0c;也是用来对响应式数据做处理&#xff0c;那就是 shallowReactive 与 shallowRef shallowReactive 文档解释&#xff1a;reactive() 的浅层作用形式&#xff0c;只能定义对象类型的数据。和 r…

pytorh基础知识和函数的学习:图像文件的Tensor

在深度学习和计算机视觉中&#xff0c;将图像文件转换为张量&#xff08;Tensor&#xff09;是数据预处理的重要步骤。Tensor 是一种多维数组&#xff0c;在 PyTorch 中&#xff0c;用于表示和处理数据。 首先&#xff0c;创建一个3*3的图像文件&#xff0c;放大之后&#xff…

终端防火墙软件功能 | 在终端设备上启用防火墙!终端安全小课堂开讲啦

终端设备的安全性直接关系到企业的整体网络安全&#xff0c;随着网络威胁的日益复杂和多样化&#xff0c;启用并合理配置终端防火墙软件是保障终端安全不可或缺的一环。 今天&#xff0c;我们将走进终端安全小课堂&#xff0c;详细解析安企神终端安全管理软件中的防火墙功能&a…