二叉树--堆
二叉树-堆
- 一、堆的概念及结构
- 1.1 堆的概念与结构
- 1.2 堆的性质
- 二、堆的实现
- 三、堆的应用
- 1、堆排序
一、堆的概念及结构
1.1 堆的概念与结构
堆就是完全二叉树以顺序存储方式存储于一个数组中。

然后每一个根都大于它的左孩子和右孩子的堆,我们叫做大堆,上图就是一个典型的大堆,小堆就是每一个根都小于它的左孩子和右孩子的堆。

这个就是一个小堆。
1.2 堆的性质
1、堆中某个结点的值总是不大于或不小于其父结点的值;
2、堆总是一棵完全二叉树
3、
这里的规律在堆的实现中会使用到,希望大家可以记住。
二、堆的实现
我们这里使用的是顺序结构,所以我们可以采用之前的顺序表来存储。
1、先定义一个堆
typedef int type;typedef struct Heap
{type* arr;int size;int capacity;
}HP;
这一部分在之前顺序表的章节讲过,所以在这里我就不多讲了。
2、堆的初始化和销毁。
void HpInit(HP* ptr)
{assert(ptr);ptr->arr = NULL;ptr->capacity = ptr->size = 0;
}
void HpDestroy(HP* ptr)
{assert(ptr);free(ptr->arr);ptr->capacity = ptr->size = 0;
}
3、堆的插入
插入部分跟之前一样,但是我们插入后需要进行一系列操作

比如说现在我们将1插入,但是我们插完1后还是小堆吗?那我们是不是要让这个1向上调整啊,我们的向上调整走的是下面的过程:

如果孩子小于父亲,孩子和父亲就交换,直到父亲小于孩子(小堆),大堆则反过来。
代码:
void swap(int* p, int* q)//交换父亲和孩子,这一部分向下调整也会用到,所以封装起来
{int tep = *p;*p = *q;*q = tep;
}
void adjustUp(type* arr, int size)
{int child = size - 1;//size是数组元素个数,下标等于元素个数 -1int parent = (child - 1) / 2;//根据上面的公式,用孩子求父亲while (child > 0){if (arr[parent] > arr[child]){swap(&arr[parent], &arr[child]);child = parent;parent = (child - 1) / 2;}elsebreak;}
}
void HpPush(HP* ptr, type x)
{assert(ptr);if (ptr->capacity == ptr->size){int newcapacity = ptr->capacity == 0 ? 4 : 2 * ptr->capacity;type* tep = (type*)realloc(ptr->arr, sizeof(type)* newcapacity);if (tep == NULL){perror("realloc");return;}ptr->arr = tep;ptr->capacity = newcapacity;}ptr->arr[ptr->size++] = x;adjustUp(ptr->arr, ptr->size);
}
那上面的会写了以后,我们再想想我们怎样将一个数组给建成堆呢?
我们是不是可以将数组一个元素一个元素的入堆,每入一个元素就向上调整一次,那这样我们的堆是不是就建好了。

大家可以看到我们成功的建了一个小堆。
4、堆的删除
堆的删除跟之前不太一样,我们要是删除堆最后一个元素,对我们的堆有影响吗?
所以我们删除的是堆顶的元素,在删除堆顶的元素后要保证我们还是一个大堆或者小堆。
如果我们直接删就会出现下面的情况:

所以我们要先进行一步操作,交换第一个元素和最后一个元素,这样我们删除最后一个元素是不会影响我们的堆的次序的,然后我们在进行一个向下调整,在调整时我们一定要想好交换哪个孩子,如果我们建的是小堆,那么就交换我们小的孩子,大堆就交换大的孩子。

代码:
void adjustDown(type* 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[parent] > arr[child]){swap(&arr[parent], &arr[child]);parent = child;child = parent * 2 + 1;}elsebreak;}
}
void HpPop(HP* ptr)
{assert(ptr);swap(&ptr->arr[0], &ptr->arr[ptr->size - 1]);ptr->size--;adjustDown(ptr->arr, 0, ptr->size);
}
5、取堆顶元素
这块比较简单,我就直接给代码了
type HpTop(HP* ptr)
{assert(ptr);assert(ptr->size > 0);return ptr->arr[0];
}
6、判空
bool HpisEmpty(HP* ptr)
{assert(ptr);return ptr->size == 0;
}
7、直接用顺序表建堆
上面我们是将元素放入我们的堆后再进行其他操作,但实际上我们可以直接在顺序表里建堆。

这样就直接建堆了,这里是将数组看做完全二叉树。
三、堆的应用
1、堆排序
堆排序就是后面我们所说的八大排序之一的堆排,那这个怎么实现?

堆排序走的是这样的一个过程,首先先建好一个堆,然后交换第一个元素和最后一个元素,因为堆顶一定是我们最大或最小的元素,所以最后一个元素就排好了,接下来我们进行一次向下调整,选出次小的在我们的堆顶,然后交换堆顶与倒数第一个元素,这样倒数第二个元素就排好了,直到排完整个数组。

这里我排的是逆序的,为什么这里是逆序的呢?这是因为我们建的小堆,我们选小的在我们的数组末尾,那我们是不是可以总结一个规律啊!
建大堆——排升序
建小堆——排逆序
2、向下调整建堆
这个算法虽然可以用,但是它的效率并没有我们的向上调整建堆高,所以这里我不讲。
7、TopK
上面这些完成了我们就可以简单的打印我们这里的排序了,这个问题也叫做TopK问题,注意的是这里并没有进行排序,只是将我们有序的数给打印出来。
void test1()
{HP hp;HpInit(&hp);int arr[] = { 1,5,2,8,0,4,3,7 };for (int i = 0; i < sizeof(arr) / sizeof(int); i++){HpPush(&hp, arr[i]);}//可以将我们的排序打印出来,但是这里并没有进行真正的排序while (!HpisEmpty(&hp)){printf("%d ", HpTop(&hp));//取堆顶元素,直到堆为空HpPop(&hp);//取一个元素,删除一个元素}HpDestroy(&hp);
}
int main()
{test1();return 0;
}
这里我写的时候元素给的比较少,我们可以改一下,

这里我们在数组里放了10000个元素,然后我们求最小的10个,这就是TopK。
总的来说这一章难度在上升,大家下来多理解这里的向上调整、向下调整以及我们的排序的过程,相信大家一定可以学好的。
相关文章:
二叉树--堆
二叉树-堆 一、堆的概念及结构1.1 堆的概念与结构1.2 堆的性质 二、堆的实现三、堆的应用1、堆排序 一、堆的概念及结构 1.1 堆的概念与结构 堆就是完全二叉树以顺序存储方式存储于一个数组中。 然后每一个根都大于它的左孩子和右孩子的堆,我们叫做大堆ÿ…...
【K8s】专题十二(2):Kubernetes 存储之 PersistentVolume
本文内容均来自个人笔记并重新梳理,如有错误欢迎指正! 如果对您有帮助,烦请点赞、关注、转发、订阅专栏! 专栏订阅入口 Linux 专栏 | Docker 专栏 | Kubernetes 专栏 往期精彩文章 【Docker】(全网首发)Kyl…...
python3多个图片合成一个pdf文件,生产使用验证过
简单的示例代码,展示如何将多个图片合成为一个 PDF 文件。 步骤 1: 安装依赖库 首先,确保你已经安装了 Pillow 和 reportlab 库: pip install Pillow reportlab步骤 2: 编写代码 下面是一个 Python 脚本,它将指定目录中的所有图片文件合成一个 PDF 文件: from PIL im…...
Stable Diffusion赋能“黑神话”——助力悟空走进AI奇幻世界
《黑神话:悟空》是由游戏科学公司制作的以中国神话为背景的动作角色扮演游戏,将于2024年8月20日发售。玩家将扮演一位“天命人”,为了探寻昔日传说的真相,踏上一条充满危险与惊奇的西游之路。 同时,我们还可以借助AI绘…...
微信小程序登陆
一 问题引入 我们之前的登陆都是:网页http传来请求,我们java来做这个请求的校验。 但是如果微信小程序登陆,就要用到相关的api来实现。 二 快速入门 1 引入依赖 官方依赖,在里面找合适的,去设置版本号。由于我这…...
SQL - 存储过程
假设你在开发一个应用,应用有一个数据库,你要在哪里写SQL语句?你不会在你的应用代码里写语句,它会让你的应用代码很混乱且难以维护。具体在哪里呢?在存储过程中或函数中。存储过程是一组为了完成特定功能的SQL语句集合…...
RabbitMQ环境搭建
2.5.RabbitMQ 安装 a.docker方式安装: 1.在我的docker学习笔记中具有详细的安装过程 b.rpm包方式安装: 1.MQ下载地址2.这里是提前下载好后上传安装包到服务器得opt目录下: 3.安装MQ需要先有Erlang语言环境,安装文件的Linux命令…...
多视点抓取(Multi-View Grasping)
目录 前言 一、在机器人抓取检测领域里,多视点抓取是什么意思 二、以GG-CNN为例,GG-CNN是怎么结合多个视点进行抓取预测的 前言 多视点抓取(Multi-View Grasping)是机器人抓取和检测领域的一个重要概念,它涉及到机器…...
【人工智能】对智元机器人发布的远征A1所应用的AI前沿技术进行详细分析,基于此整理一份学习教程。
智元机器人在其新品发布中应用了多项AI前沿技术。我们可以从以下几个方面来分析和整理这些技术,并基于此整理一份学习教程: 一、智元机器人应用的关键AI技术 自然语言处理 (NLP) 语音识别: 利用先进的语音识别技术,如OpenAI的Whisper&#x…...
影刀RPA--如何获取网页当页数据?
(1)点击数据抓取-选择需要获取数据的地方-会弹出是否是获取整个表格(当前页面) (2)点击“是”:则直接获取整个表格数据-点击完成即可 (3)点击“否”:如果你想…...
Bean对象生命周期流程图
Bean生命周期流程图:https://www.processon.com/view/link/5f8588c87d9c0806f27358c1 Spring扫描底层流程:https://www.processon.com/view/link/61370ee60e3e7412ecd95d43...
24/8/17算法笔记 策略梯度reinforce算法
import gym from matplotlib import pyplot as plt %matplotlib inline#创建环境 env gym.make(CartPole-v0) env.reset()#打印游戏 def show():plt.imshow(env.render(mode rgb_array))plt.show() show()定义网络模型 import torch #定义模型 model torch.nn.Sequential(t…...
【Linux学习】Linux开发工具——vim
🔥个人主页: Forcible Bug Maker 🔥专栏:Linux学习 目录 🌈前言🔥vim的基本概念🔥vim的基本操作🔥vim命令模式的命令集🔥简单vim配置⭐一键配置美观的vim安装方法卸载方…...
【2025校招】4399 NLP算法工程师笔试题
目录 1. 第一题2. 第二题3. 第三题 ⏰ 时间:2024/08/19 🔄 输入输出:ACM格式 ⏳ 时长:2h 本试卷分为单选,自我评价题,编程题 单选和自我评价这里不再介绍,4399的编程题一如既往地抽象ÿ…...
数据库原理--关系1
目录 一、表的基本构成要素 二、域(Domain) 三、笛卡尔积 四、关系模式 五、关系模式与关系 六、关系的特性 一、表的基本构成要素 表又被叫做关系,在数据库当中,我们可以把行叫做元组和记录,而列在数据库当中通常被我们叫做字段或者…...
【人工智能】AI工程化是将人工智能技术转化为实际应用、创造实际价值的关键步骤
AI工程化是将人工智能技术转化为实际应用、创造实际价值的关键步骤。以下是对AI工程化的详细介绍: 一、概念与定义 AI工程化是使用数据处理、预训练模型、机器学习流水线等技术开发AI软件的过程,旨在帮助企业更高效地利用AI创造价值。它是软件工程在AI…...
《C语言实现各种排序算法》
文章目录 一、排序1、排序的各种方式分类 二、插入排序1、直接插入排序2、希尔排序3、希尔排序时间复杂度分析 三、选择排序1、直接选择排序2、堆排序 四、交换排序1、冒泡排序2、快速排序3、快速排序hoare找基准值4、快排挖坑法找基准值5、前后指针法6、快速排序非递归实现 五…...
【888题竞赛篇】第五题,2023ICPC澳门-传送(Teleportation)
这里写自定义目录标题 更多精彩内容256题算法特训课,帮你斩获大厂60W年薪offer 原题2023ICPC澳门真题传送B站动画详解 问题分析思路分析图的构建最短路径算法具体步骤 算法实现Dijkstra 算法图的构建 代码详解标准代码程序C代码Java代码Python代码Javascript代码 复…...
javascript写一个页码器-SAAS本地化及未来之窗行业应用跨平台架构
一代码 接引入 <script type"text/javascript" src"CyberWin_APP_Page.js" alt"未来之窗页码"></script>function 未来之窗页面触发器(页码){console.log("当前用户新"页码);}CyberWin_Page.set_callback(未来之窗页面触发…...
微信小程序如何自定义一个组件
微信小程序支持组件化开发,这有助于我们复用代码,提高开发效率。下面我将给出一个简单的微信小程序组件化示例,包括一个自定义组件的创建和使用。 1. 创建自定义组件 首先,在项目的 components 目录下创建一个新的组件文件夹&am…...
WandEnhancer技术解密:如何通过本地化增强重新定义游戏修改体验
WandEnhancer技术解密:如何通过本地化增强重新定义游戏修改体验 【免费下载链接】Wand-Enhancer Advanced UX and interoperability extension for Wand (WeMod) app 项目地址: https://gitcode.com/gh_mirrors/we/Wand-Enhancer 你是否曾经面对游戏修改工具…...
3个步骤让Windows任务栏图标居中,打造macOS般的桌面体验
3个步骤让Windows任务栏图标居中,打造macOS般的桌面体验 【免费下载链接】TaskbarX Center Windows taskbar icons with a variety of animations and options. 项目地址: https://gitcode.com/gh_mirrors/ta/TaskbarX 你是否厌倦了Windows任务栏图标总是靠左…...
从TPM到机密计算:远程证明技术原理与zap1项目实践指南
1. 项目概述与核心价值最近在整理一些零散的学习笔记时,发现了一个挺有意思的项目,叫Frontier-Compute/zap1-learning-attestation。乍一看这个标题,可能有点让人摸不着头脑,尤其是对于刚接触可信计算或者硬件安全领域的朋友来说。…...
XHS-Downloader:小红书内容采集与管理的全栈解决方案
XHS-Downloader:小红书内容采集与管理的全栈解决方案 【免费下载链接】XHS-Downloader 小红书(XiaoHongShu、RedNote)链接提取/作品采集工具:提取账号发布、收藏、点赞、专辑作品链接;提取搜索结果作品、用户链接&…...
3D打印乐高手机支架:低成本打造高清视频会议摄像头方案
1. 项目概述与核心思路如果你和我一样,对视频会议、直播时笔记本自带摄像头那“感人”的画质感到无奈,同时又觉得单独购买一个高品质的网络摄像头是一笔不小的开销,那么这个项目绝对值得你花上一个周末的时间来折腾。它的核心思路非常巧妙&am…...
All in Token,移动,电信,联通,百度,阿里,字节,华为,Token战争,Token无用:李彦宏用DAA终结了AI的度量衡之争
今年4月,AI行业出现了一组让投资人坐立难安的数据:Anthropic年化营收突破300亿美元,正式超过OpenAI的约250亿美元。但反常的是,据第三方机构估算,Claude的月活用户仅约为ChatGPT的2.44%。以及,Anthropic的模…...
量化交易强化学习环境TradingGym:从Gym接口到实战策略训练
1. 项目概述:一个为量化交易策略量身定制的强化学习训练场如果你正在尝试将强化学习(Reinforcement Learning, RL)应用到股票、期货或加密货币的量化交易中,大概率会遇到一个共同的困境:环境太难搭了。市面上的回测框架…...
人性最残忍的真相是:你越不把自己当回事,别人就越不把你当回事
那个总给别人买贵东西的人,最后都怎么样了? 目录 那个总给别人买贵东西的人,最后都怎么样了? 我们为什么会忍不住过度付出? 真正的爱,从来都不是单方面的牺牲 爱自己,是所有健康关系的前提 昨天刷到一句话,瞬间戳中了我:“永远不要拿自己辛苦钱,去给别人买自己都舍不…...
AXI交叉开关IP核:SoC内部高并发数据传输的核心枢纽设计与实战
1. 项目概述:一个高效、可配置的片上总线交叉开关在复杂的数字系统设计,尤其是片上系统(SoC)领域,多个主设备(如CPU、DMA控制器)需要同时访问多个从设备(如内存、外设控制器…...
蜘蛛池技术解析:网站收录提速的关键工具与运营策略
在搜索引擎优化领域,蜘蛛池是助力网站收录提速的重要辅助工具,尤其适配新站、低权重站或海量内容站,能有效破解收录慢、收录少、深层页面难抓取等痛点。本文从技术原理、核心价值、搭建要点及合规运营策略四方面,全面解析蜘蛛池的…...
