数据结构:堆的创建和使用

上一期我们学习了树和二叉树的定义,其中我们了解到了两种特殊的二叉树:满二叉树和完全二叉树。

今天我们还要学习一种新的结构:堆

那这种结构和二叉树有什么联系呢???

通过观察我们可以发现,完全二叉树和满二叉树可以看作是一个连续的结构,所以我们可以使用顺序存储,但是这种结构还不算是堆结构,那么堆又和这种结构有什么联系呢???

 下面是两种堆的结构:一种是大堆,一种是小堆

那么什么是大堆和小堆呢?

顾名思义,小堆就是根节点都比孩子结点小的

大堆就是根节点都比孩子结点大的

下面就是两种堆的结构:

  那么我们学习堆有什么意义呢?下面是堆的几种运用场景:

后面我们会有所了解。

 

这里我们先来了解一下堆排序

通过对比我们可以发现,堆排序相比冒泡排序的时间复杂度是远远要好的

下面我们就正式进入堆的学习中。

 我们先来看堆的定义:

因为堆是顺序结构,所以我们定义的方式和顺序表是一致的。

 在实现堆中我们需要使用两种算法,一种是向上调整算法,一种是向下调整算法。

 (假设在小堆中)在向上调整算法中,我们插入50,我们需要将它的值与根节点的值进行比较,

如果比根节点小我们就进行交换。直到我们的孩子结点走到最顶端,也就是下标为0的位置。

 那么我们要怎么寻找每次的孩子结点和父结点的下标呢?

通过观察我们可以发现孩子结点和自己的父结点有以下规律:

 所以每一次结束比较后我们都要将父结点赋值给孩子节点,并让父结点走向当前孩子结点的父结点。所以下面是代码的实现

 所以在堆中我们每次插入数据都需要调整值的顺序。但是,我们思考后会发现,我们的向上和向下调整算法都只能调整父结点和孩子结点的关系,而不能改变兄弟结点的关系

所以我们的堆插入数据的函数如下

 下面我们来写“删除堆顶元素”函数

我们将堆顶元素认为是下标为0所在位置的元素,有一些人就想当然将后面的数据覆盖上去,但是,这一种思路是不对的,我们仔细思考一下,我们这样子做,我们的结点间的父子关系就全都不对了,也就是我们的堆就不是堆了,顺序已经被打乱了

那么我们应该怎么做呢???

这里我们的另一种向调下整算法就起到了重要的作用。

删除时,首先我们将首元素和末尾元素的值交换,之后我们只要将size--就可以删除尾部元素,也就是原来的堆顶的元素,之后我们再将堆顶的元素向下调整。

那么向下调整的算法是怎样书写的呢???

向下调整中,我们定义父结点,之后通过上面的父结点和子节点的关系,我们可以找到左子节点,

左子节点和右子节点下标相差1,我们通过比较左子节点和右子节点的值,我们选出最小的,若此时的父结点的值大于最小的子节点,我们就进行交换,之后一直走循环,直到父结点走到动态数组的最后面

下面是向下调整算法的书写 

 下面是删除堆顶元素的函数:

 其中HPEmpty函数是判断堆是否为空的函数

 到这里我们就可以解决topk问题,比如我们要取出一千万数的前十名,我们就可以返回堆顶元素,之后pop9次就可以了。

这里我们要了解topk问题的具有现实的意义,比如我们在点外卖时,我们要选取销量前十的我们就可以使用topk解决问题

下面是全部代码

void HPInit(HP* php)//初始化堆堆空间
{php->size = 0;php->a = NULL;php->capcity = 0;
}
void swap(int* p1, int* p2)
{int tmp = *p1;*p1 = *p2;*p2 = tmp;
}//交换函数
void AdjustUp(int* a, int Child)
{int child = Child;int parent = (child - 1) / 2;while(child > 0)//直到孩子结点走到下标为0的位置{if (a[child] < a[parent]){swap((a) + child, (a) + parent);//发现子节点的值比父节点小就进行交换child = parent;//将父结点赋值给孩子结点parent = (child - 1) / 2;//走向下一个父结点}else{break;//若孩子结点大就退出循环,即不需要交换}}return;
}
void HPPush(HP* php, HPDatatype x)//插入数据
{if(php->size == php->capcity){int newcapcity = php->capcity == 0 ? 4 :php->capcity * 2;//看空间是否足够HPDatatype* a = (HPDatatype*)realloc(php->a, sizeof(HPDatatype) * newcapcity);if (a == NULL){perror("malloc_fail");return;}php->a = a;php->capcity = newcapcity;}php->a[php->size] = x;php->size++;//开辟新的空间并存放数据AdjustUp(php->a,php->size - 1);//通过向上调整顺序形成小堆
}
bool HPEmpty(HP* php)
{return php->size == 0;
}
void AdjustDown(int* a,int n ,int parent)
{assert(a);int child = parent * 2 + 1;while(child < n){if (child + 1 < n && a[child] > a[child + 1])//选出较小的子节点{child += 1;}if (a[parent] > a[child])//父节点都比两个子节点小就返回{swap(a + parent, a + child);//与较小的子节点交换位置//往下再寻找parent = child;child = parent * 2 + 1;}else{break;//若父结点的值小于最小子节点的值我们就退出循环,即这个堆还是小堆}}
}
void HPPop(HP* php)//删除堆顶元素
{assert(php);assert(!HPEmpty(php));swap(php->a, php->a + php->size - 1);//交换顶部元素和底部元素php->size--;AdjustDown(php->a,php->size,0);//向下调整
}
int HPTop(HP* php)//返回堆顶的元素
{return php->a[0];
}
void HPDestroy(HP* php)//销毁堆空间
{assert(php);free(php->a);php->a = NULL;
}

以上就是本次的全部内容,谢谢大家观看!!!

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

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

相关文章

鸿蒙一次开发,多端部署(三)应用UX设计原则

设计原则 当为多种不同的设备开发应用时&#xff0c;有如下设计原则&#xff1a; 差异性 充分了解所要支持的设备&#xff0c;包括屏幕尺寸、交互方式、使用场景、用户人群等&#xff0c;对设备的特性进行针对性的设计。 一致性 除了要考虑每个设备的特性外&#xff0c;还…

C# 读取二维数组集合输出到Word预设表格

目录 应用场景 设计约定 范例运行环境 配置Office DCOM 实现代码 组件库引入 核心代码 DataSet转二维数组 导出写入WORD表格 调用举例 小结 应用场景 存储或导出个人WORD版简历是招聘应用系统中的常用功能&#xff0c;我们通常会通过应用系统采集用户的个人简历信息…

云主机搭建与服务软件部署

文章目录 登录访问云电脑与云电脑传输文件配置ssh服务ssh连接云电脑使用scp传输文件云端服务软件部署与实现外部访问首先购买云主机,以阿里云服务器 ECS为例子,官网购买就行了,选择默认安装了windows server 2022服务器系统 登录访问云电脑 购买完成进入控制台,能看到创建…

使用CUDA 为Tegra构建OpenCV

返回&#xff1a;OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 上一篇&#xff1a;MultiArch与Ubuntu/Debian 的交叉编译 下一篇&#xff1a;在iOS中安装 警告&#xff1a; 本教程可能包含过时的信息。 使用CUDA for Tegra 的OpenCV 本文档是构建支持 CUD…

谷歌具身智能最新进展:RT-H 机器人通用灵巧抓取

随着 GPT-4 等大型语言模型与机器人研究的结合愈发紧密&#xff0c;人工智能正在越来越多地走向现实世界&#xff0c;因此具身智能相关的研究也正受到越来越多的关注。在众多研究项目中&#xff0c;谷歌的「RT」系列机器人始终走在前沿&#xff08;参见《大模型正在重构机器人&…

各位老板,你需要的工厂数字孪生可视化库在这

各位老板是不是很喜欢下面这种有逼格的大屏,下面介绍一下怎么实现的,保证有所收获。 Cesium是一个开源的WebGL JavaScript库&#xff0c;用于创建高性能的三维地球、地图和虚拟环境。它支持在浏览器中实现高质量的地球模拟&#xff0c;同时提供了丰富的功能特点&#xff0c;使得…

k8s系列之十五 Istio 部署Bookinfo 应用

Bookinfo 应用中的几个微服务是由不同的语言编写的。 这些服务对 Istio 并无依赖&#xff0c;但是构成了一个有代表性的服务网格的例子&#xff1a;它由多个服务、多个语言构成&#xff0c;并且 reviews 服务具有多个版本。 该应用由四个单独的微服务构成。 这个应用模仿在线书…

模板高级使用(非类型模板参数,特化,分离编译)

文章目录 模板没有实例化取内嵌类型报错问题非类型模板参数模板的特化函数模板的特化类模板的特化1.全特化2.偏特化 模板的分离编译 模板没有实例化取内嵌类型报错问题 首先在这里分享一个模板的常见报错问题。就是模板的在没有实例化的情况下去取模板类里面的内嵌类型这时候的…

代码随想录|Day25|回溯05|491.非递减子序列、46.全排列、47.全排列II

491. 非递减子序列 本题并不能像 90.子集II 那样&#xff0c;使用排序进行树层去重。虽然题目没有明确不能排序&#xff0c;但如果排序了&#xff0c;集合本身就是递增子序列&#xff0c;这是LeetCode示例2中没有出现的。 所以本题的关键在于&#xff0c;如何在不排序的情况下对…

2024格行VS华为VS飞猫哪个是最值得购买随身WiFi?中兴随身WiFi好用吗?

经常出差旅行&#xff0c;或者户外工作的朋友因为长期在外&#xff0c;手机流量经常不够用&#xff0c;想必都是随身WiFi的忠实用户&#xff0c;但是也都被这款产品割韭菜割的头皮发麻。今天&#xff0c;我们统计了市面上最靠谱的、最热销、口碑最好的几款随身WiFi。排名依据来…

Java学习笔记(17)

集合进阶 单列集合 Collection List set Add clear remove contains isempty size Add方法可能也会添加失败 同理&#xff0c;可能删除失败 Contains细节 为什么要重写equals&#xff1f; 因为contains底层用的是object类中的equals方法&#xff0c;比较的是地址值&#xf…

为什么穷人什么都懂,就是不懂赚钱?2024金矿项目! 2024创业好项目 !2024创业新项目新商机! 2024超级机会

为什么穷人什么都懂&#xff0c;就是不懂赚钱&#xff1f;有位网友是这么说的&#xff0c;穷人的思维有一个致命的缺陷&#xff0c;就是追求确定性&#xff0c;进而失去了可能性。而赚钱的真相实际上非常残酷。世界上能够赚钱的事情必定是不确定的&#xff0c;能够赚取巨额财富…

万亿参数GPU!算力提升30倍!英伟达新核弹B200重磅发布!

关注文章底部的公众号,获取每日AI资讯 前沿 3月18日-21日期间,英伟达在美国圣何塞召开GTC大会。创始人黄仁勋也在GTC大会上,做了一场长达两小时的开幕演讲,展示了其在AI芯片、机器人、汽车等领域的最新研发成果和技术进展,号称让全世界用上AI。 全球头号人工智能领域开发…

算法第三十一天-直方图的水量

直方图的水量 题目要求 解题思路 使用面向列的计算比面向行的计算更加容易。我们只需要考虑当前的位置的左右最高模板的高度。 方法一、暴力解法 每个位置能接到多少雨水&#xff0c;很容易想到[木桶效应]&#xff0c;即是由两边最短的木板限制的。那么直观思路就是&#x…

扶贫惠农推介系统|基于jsp技术+ Mysql+Java+ B/S结构的扶贫惠农推介系统设计与实现(可运行源码+数据库+设计文档)

推荐阅读100套最新项目 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 2024年56套包含java&#xff0c;ssm&#xff0c;springboot的平台设计与实现项目系统开发资源&#xff08;可…

Python学习:元组

Python 元组概念 Python 中的元组&#xff08;tuple&#xff09;是不可变的有序集合。它是一种数据类型&#xff0c;类似于列表&#xff08;list&#xff09;&#xff0c;但在创建后不能被修改。元组使用圆括号 () 来表示&#xff0c;其中的元素可以是任意类型&#xff0c;并且…

初识数据库原理:为什么需要数据库?

初识数据库原理&#xff1a;什么是数据库&#xff1f; Chapter1&#xff1a;什么是数据库&#xff1f; 笔记来源&#xff1a;《漫画数据库》–科学出版社 1.1 为什么需要数据库&#xff1f; 文件应用的管理方式&#xff0c;数据会出现重复。 若各个部门各自管理自己一方的数…

2024年【T电梯修理】考试内容及T电梯修理作业考试题库

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 T电梯修理考试内容根据新T电梯修理考试大纲要求&#xff0c;安全生产模拟考试一点通将T电梯修理模拟考试试题进行汇编&#xff0c;组成一套T电梯修理全真模拟考试试题&#xff0c;学员可通过T电梯修理作业考试题库全真…

Linux手动创建用户不使用useradd【七步走完成】

文章目录 第一步&#xff1a;修改 /etc/passwd 文件第二步&#xff1a;修改 /etc/shadow 文件第三步&#xff1a;修改 /etc/group 文件第四步&#xff1a;新建用户家目录第五步&#xff1a;复制/etc/skel目录下的环境变量配置文件到家目录下第六步&#xff1a;修改家目录的权限…

AI系统性学习—LangChain入门

文章目录 1、LangChain入门1.1 简介1.2 架构1.3 核心概念1.2 快速入门1.3 安装 2、LangChain Prompt Template2.1 什么是提示词模版2.1 创建一个提示词模版2.2 聊天消息提示词模版2.3 模版追加示例 3、语言模型3.1 LLM基础模型3.2 LangChain聊天模型3.3 自定义模型3.4 输出解析…