二叉树之堆的应用

目录

堆排序

思路详解

Ⅰ 建堆

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

功能接口

向上调整算法

向下调整算法

主函数

运行结果展示

TOP - K问题

思路详解

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

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

功能接口

建小堆所需的向上调整算法

向下调整算法

创建数据集合的文件创建接口

堆排序接口

 TOP-K

运行结果展示

结语


堆排序

所谓堆排序,即是使用堆的思想来进行排序。

在堆中,我们逻辑上想象他是一棵树,但实际在物理上它是一个数组。

思路详解

Ⅰ 建堆

如果我们要将数据升序排列,那我们需要建大堆,如果降序排列,则建小堆。

升序:建大堆;

降序:建小堆。

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

以升序为例,假设此时我们已经完成了大堆的创建。

还记得堆是如何删除的吗?

我们将堆顶与堆尾互换,然后删除堆尾,再向下调整。

但在堆排序中,我们互换之后并不删除堆尾,只是不再对堆尾进行操作。

试想,一个大堆,堆顶元素自然是最大的数据,当我们交换堆顶堆尾,最大的元素就到了堆尾,我们不再对其进行操作,逻辑上将其暂时剥离数组,随后再进行向下调整。循环往复。

我们来画图看看:

功能接口

有关堆的一些基础特性可查看我的另一篇文章。数据结构之树 --- 二叉树-CSDN博客

向上调整算法

该接口建堆时使用。

//小堆
void SmaADjustUP(int* a, int child)
{int parent = (child - 1) / 2;while (child >= 0){if (a[child] < a[parent]){swap(&a[child], &a[parent]);child = parent;parent = (parent - 1) / 2;}elsebreak;}
}

向下调整算法

void SmaADjustDown(int *a,int size,int parent)
{int child = parent * 2 + 1;while (child < size){if (child+1 < size && a[child] > a[child + 1]){child = child + 1;}if (a[child] < a[parent]){swap(&a[child], &a[parent]);parent = child;child = parent * 2 + 1;}elsebreak;}
}

 当然,只使用向下调整算法也是可以的。

主函数

步骤操作在代码中有注释。

int main()
{int a[10] = { 2,5,3,9,6,8,7,1,10 };int len = 10;for (int i = 0; i < len; i++)//建堆{BigADjustUP(a,i);}while(len>0){swap(&a[0], &a[len - 1]);//交换堆顶与堆尾BigADjustDown(a, len - 1, 0);//向下调整,注意此时传入的数组大小为len-1,并未将堆尾传入//即向下调整时不包括堆尾len--;//剥离堆尾}for (int i = 0; i < 10; i++)//打印操作{printf("%d ", a[i]);}return 0;
}

运行结果展示

TOP - K问题

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

比如:专业前10名、世界500强、富豪榜、游戏中前100的活跃玩家等。
对于Top-K问题,能想到的最简单直接的方式就是排序,但是:如果数据量非常大,排序就不太可取了(可能数据都不能一下子全部加载到内存中)。最佳的方式就是用堆来解决,

思路详解

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

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

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

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

以建小堆为例,我们要求前5个最大的元素。

假设此时我们已经建好5个元素的小堆,将剩余的元素依次与堆顶进行比较,如果大于堆顶,则与堆顶交换,然后进行向下调整算法,使堆时刻保持特性。直至集合中的数据全部比较完成,此时堆中的五个数就是数据集合中最大的五个数。

我们来看看例子 

按照上图方法比对,直至数据集合结束。

功能接口

建小堆所需的向上调整算法

向下调整算法

以上两个函数接口在堆排序中已经给出来了。

创建数据集合的文件创建接口

由于TOP-K问题一般用来处理大数据,因此我们需要创建一个乱序的含有大量数据的数据集合。

我们创建一个文件,向文件内写入一定数量的随机值,然后对文件中的数据进行操作。

void CreateFile(int n)
{srand(time(0));//const char* file = "data.txt";FILE* fin = fopen("data.txt", "w");if (fin == NULL){perror("fopen error");return;}for (int i = 0; i < n; i++){int num = (rand() + i) % 10000;fprintf(fin, "%d\n", num);}fclose(fin);
}

该过程我们需要用到 rand() 函数。

堆排序接口

将最后小堆中的数据进行升序排列

void heapSort(int* a, int len)
{int size = len;for (int i = 0; i < size; i++){swap(&a[0], &a[len - 1]);SmaADjustDown(a, len - 1, 0);len--;}for (int i = 0; i < size; i++){if (i % 5 == 0)printf("\n");printf("%d ", a[i]);}
}

 TOP-K

在该函数中,我们调用创建文件接口,完成数据集合文件的创建,然后取k个数建堆。

接下来将剩下的数据依次与堆顶比对,向下调整。

void PrintTopk(int n,int k)
{CreateFile(n);//创建数据集合的文件FILE* fout=fopen("data.txt", "r");if (fout == NULL){perror("fopen errorPrint");return;}int* a = (int*)malloc(sizeof(int) * k);//开辟堆空间for (int i = 0; i < k; i++)//建k个数的堆{fscanf(fout,"%d",&a[i]);SmaADjustUP(a, i);}int tmp = 0;while (fscanf(fout, "%d", &tmp)!=EOF)//直至文件内的数据取完{if (tmp > a[0]){a[0] = tmp;SmaADjustDown(a, k, 0);}}heapSort(a, k);free(a);fclose(fout);
}

运行结果展示

这里创建了含有10000个整型数据的数据集合。

数据集合的文件: 

结语

关于堆的学习,我们就告一段落了,欢迎各位翻阅指正。 

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

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

相关文章

算法刷题:最大异或对(Trie树扩展)、食物链(并查集扩展)

目录 引言一、最大异或对&#xff08;Trie树扩展&#xff09;1.题目描述2.解题思路3.代码实现4.测试 二、食物链&#xff08;并查集扩展&#xff09;1.题目描述2.解题思路3.代码实现4.测试 引言 这两个扩展题能够让我们更加的熟悉Trie树和并查集的使用&#xff0c;这两道题可以…

MySQL:子查询

子查询 子查询是嵌套在较大查询中的 SQL 查询&#xff0c;也称内部查询或内部选择&#xff0c;包含子查询的语句也称为外部查询或外部选择。简单来说&#xff0c;子查询就是指将一个 select 查询&#xff08;子查询&#xff09;的结果作为另一个 SQL 语句&#xff08;主查询&a…

Leetcode的AC指南 —— 哈希法/双指针:15. 三数之和

摘要&#xff1a; Leetcode的AC指南 —— 15. 三数之和。题目介绍&#xff1a;给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] 0 。请 你返回所有和为 0 且…

Android—— MIPI屏调试

一、实现步骤 1、在kernel/arch/arm/boot/dts/lcd-box.dtsi文件中打开&dsi0节点&#xff0c;关闭其他显示面板接口&#xff08;&edp_panel、&lvds_panel&#xff09; --- a/kernel/arch/arm/boot/dts/lcd-box.dtsib/kernel/arch/arm/boot/dts/lcd-box.dtsi-5,14 …

水库大坝安全监测设计与施工经验

随着我国的科技水平不断上升&#xff0c;带动了我国的水电建设向更高层次发展。目前&#xff0c;我国的水电站大坝已有上百座&#xff0c;并且大坝安全检测仪器质量与先进技术不断更新发展&#xff0c;如今水电站大坝数据信息采集与观测资料分析&#xff0c;能够有效提高水库大…

Linux系统安装MySQL

Linux系统安装MySQL 第一步&#xff1a;下载YUM wget http://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm第二步&#xff1a;安装MySQL的YUM 仓库 rpm -ivh mysql57-community-release-el7-11.noarch.rpm第三步&#xff1a;查看MySQL版本 yum repolist …

ESP32:整合存储配网信息和MQTT笔记

文章目录 1.给LED和KEY的所用IO增加配置项1.1 增加配置文件1.2 修改相应的c源码 2. 把mqtt\tcp的工程整合到一起2.1 在何处调用 mqtt_app_start() 3. 测试MQTT4. 完整的工程源码 有一段时间没有玩ESP32&#xff0c;很多知识点都忘记了。今天测试一下MQTT&#xff0c;做个笔记。…

基于ssm的4S店预约保养系统开发+vue论文

目 录 目 录 I 摘 要 III ABSTRACT IV 1 绪论 1 1.1 课题背景 1 1.2 研究现状 1 1.3 研究内容 2 2 系统开发环境 3 2.1 vue技术 3 2.2 JAVA技术 3 2.3 MYSQL数据库 3 2.4 B/S结构 4 2.5 SSM框架技术 4 3 系统分析 5 3.1 可行性分析 5 3.1.1 技术可行性 5 3.1.2 操作可行性 5 3…

如何成功拿下uniapp生命周期?

uniapp介绍 Uniapp作为一款跨平台应用开发框架&#xff0c;具有两个生命周期&#xff1a; 组件生命周期页面生命周期什么是页面&#xff1f; pages下面的.vue或者.nvue&#xff08;app端&#xff09;文件就是页面 什么是组件&#xff1f; 一般通常会把项目中的组件放在com…

web前端开发html/css求职简介/个人简介小白网页设计

效果图展示&#xff1a; html界面展示&#xff1a; html/css代码&#xff1a; <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns"http://www.w3.…

驶入未来:网约车运营数据揭秘与可视化大屏展示

驶入未来&#xff1a;网约车运营数据揭秘与可视化大屏展示 引言1. 数据获取与准备1.1 数据来源1.2 数据结构 2. 数据处理模块2.1 数据清洗2.2 数据转换2.3 数据整合 3. 数据可视化大屏4. 创新性可视化展示5. 应用与决策支持 结语 引言 数字化时代下&#xff0c;网约车运营数据…

轮滑培训机构会员系统,轮滑俱乐部会员卡管理软件教程

轮滑培训机构会员系统&#xff0c;轮滑俱乐部会员卡管理软件教程 一、软件程序问答 1、轮滑会员管理&#xff0c;那么会员卡是否可以直接用手机号呢&#xff1f; 如下图&#xff0c;软件以 佳易王轮滑会员管理系统V16.2为例说明 会员在登记的时候&#xff0c;会员卡可以直…

python实现图像的二维傅里叶变换——冈萨雷斯数字图像处理

原理 二维傅里叶变换是一种在图像处理中常用的数学工具&#xff0c;它将图像从空间域&#xff08;我们通常看到的像素排列&#xff09;转换到频率域。这种变换揭示了图像的频率成分&#xff0c;有助于进行各种图像分析和处理&#xff0c;如滤波、图像增强、边缘检测等。 在数学…

按摩上门预约小程序源码系统 开发组合:PHP+MySQL 附带完整的搭建教程

现代生活节奏的加快&#xff0c;人们越来越注重健康与放松。按摩作为传统的舒缓方式&#xff0c;市场需求逐年上升。然而&#xff0c;传统的按摩服务预约方式较为繁琐&#xff0c;用户需拨打热线电话或前往实体店进行预约&#xff0c;这无疑增加了用户的操作成本。因此&#xf…

【JavaScript】异步解决方案的发展历程

✨ 专栏介绍 在现代Web开发中&#xff0c;JavaScript已经成为了不可或缺的一部分。它不仅可以为网页增加交互性和动态性&#xff0c;还可以在后端开发中使用Node.js构建高效的服务器端应用程序。作为一种灵活且易学的脚本语言&#xff0c;JavaScript具有广泛的应用场景&#x…

揭秘营销返利模式!

随着互联网的普及和发展&#xff0c;越来越多的商家开始采用营销返利模式来吸引消费者。这种模式不仅可以提高销售额&#xff0c;还可以让消费者获得实实在在的优惠。本文将详细解析营销返利模式的秘密&#xff0c;让你轻松掌握这一有效的营销策略&#xff01; 一、什么是营销返…

C++继承与派生——(6)派生类的析构函数

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 站在巨人的肩上&#xff0c;是为了超过…

关于Omlox定位标准(一)——omlox hub

关于Omlox定位标准 Omlox是世界上第一个开放的定位标准&#xff0c;旨在实现灵活的实时定位解决方案&#xff0c;&#xff0c;可以使用来自各个制造商的单元。“omlox"一词源自拉丁词汇"omni”&#xff08;无处不在&#xff09;和"locus"&#xff08;位置…

18国签署,全球首份《安全AI系统开发指南》发布

内容概述&#xff1a; 2023年11月27日&#xff0c;美国、英国和其他十几个国家公布了首份关于如何保护AI免受流氓行为侵害的详细国际协议《安全AI系统开发指南》&#xff0c;敦促企业打造“设计安全”的AI系统。协议由英国国家网络安全中心&#xff08;NCSC&#xff09;主导&a…

基于电商场景的高并发RocketMQ实战-Broker写入读取流程性能优化总结、Broker基于Pull模式的主从复制原理

&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308; 【11来了】文章导读地址&#xff1a;点击查看文章导读&#xff01; &#x1f341;&#x1f341;&#x1f341;&#x1f341;&#x1f341;&#x1f341;&#x1f3…