暴力数据结构之二叉树(堆的相关知识)

1. 堆的基本了解

        堆(heap)是计算机科学中一种特殊的数据结构,通常被视为一个完全二叉树,并且可以用数组来存储。堆的主要应用是在一组变化频繁(增删查改的频率较高)的数据集中查找最值。堆分为大根堆和小根堆,大根堆中任意节点的值都大于其子树中节点的值,而小根堆则相反。堆的存储方式遵循层序遍历的规则,这样可以高效地利用存储空间。在数组中,根节点的下标为0,节点的左右孩子的下标可以通过特定的公式计算得出。堆的实现通常利用动态数组,这样可以快速扩展容量而不造成空间浪费。

堆的一些性质:1.堆中某个结点的值总是不大于或不小于其父结点的值;

                         2.堆总是一棵完全二叉树。

2. 堆的实现

 我们知道堆的逻辑结构是一个完全二叉树,但是其物理结构仍然是一个数组,所以实现堆创建一个数组即可。

typedef int HPDateType;typedef struct Heap
{HPDateType* a;int size;int capacity;
}HP;void HPInit(HP* php)
{assert(php);php->a = NULL;php->capacity = php->size = 0;
}
void HPDesTroy(HP* php)
{assert(php);free(php->a);php->a = NULL;php->capacity = php->size = 0;
}void Swap(HPDateType* p1, HPDateType* p2)
{HPDateType tmp = *p1;*p1 = *p2;*p2 = tmp;
}void AdjustUp(HPDateType* a, int child)
{int parent = (child - 1) / 2;while (child > 0){if (a[child] < a[parent]){Swap(&a[child], &a[child]);child = parent;parent = (child - 1) / 2;}else{break;}}
}void HPPush(HP* php, HPDateType x)
{if (php->capacity == php->size){int newcapacity = php->capacity == 0 ? 4 : php->capacity * 2;HPDateType* tmp = (HPDateType*)realloc(php->a, sizeof(HPDateType) * newcapacity);if (tmp = NULL){perror("realloc");return;}php->a = tmp;php->capacity = newcapacity;}php->a[php->size] = x;php->size++;AdjustUp(php->a, php->size - 1);
}
void AdjustDown(HPDateType* a, int n, int parent)
{int child = parent * 2 + 1;while (child < n){if (child + 1 < n && a[child] > a[child + 1]){child++;}if (a[child] < a[parent]){Swap(&a[child], &a[parent]);parent = child;child = parent * 2 + 1;}else{break;}}
}
void HPPop(HP* php)
{assert(php);assert(php->size > 0);Swap(&php->a[0], &php->a[php->size - 1]);php->size--;AdjustDown(php->a, php->size, 0);
}HPDateType HPTop(HP* php)
{assert(php);assert(php->size > 0);return php->a[0];
}
bool HPEmpty(HP* php)
{assert(php);return php->size == 0;
}
2.1 堆的插入

大堆的父节点均大于子节点,小堆恰好相反,自然实现逻辑各不相同,这里主要有两个主要的思想就是"父子值交换","父子址交换"。解释就是(以小堆为例):

如果对一个已有的小堆插入新的数据(叶子),如果这个叶子与他的父节点相比更小,就与父节点交换,再与交换后节点所属的父节点对比,如果还是小于就继续交换。

 代码解释如下: 

当要插入数据时先将其放在叶子节点(数组尾部),通过AdjustUp函数可以实现向上比较的动作,当然插入前判断空间是否充足,适当扩容即可。

void AdjustUp(HPDateType* a, int child)
{int parent = (child - 1) / 2;while (child > 0){if (a[child] < a[parent]){Swap(&a[child], &a[child]);child = parent;parent = (child - 1) / 2;}else{break;}}
}void HPPush(HP* php, HPDateType x)
{if (php->capacity == php->size){int newcapacity = php->capacity == 0 ? 4 : php->capacity * 2;HPDateType* tmp = (HPDateType*)realloc(php->a, sizeof(HPDateType) * newcapacity);if (tmp = NULL){perror("realloc");return;}php->a = tmp;php->capacity = newcapacity;}php->a[php->size] = x;php->size++;AdjustUp(php->a, php->size - 1);
}
2.2 堆的删除

堆的删除就是将根节点与叶子节点交换后直接删除交换后的叶子节点(即最初的跟节点数据),然后将交换后的根节点逐渐向下交换,如图所示:

 通过代码展示就是,先交换根节点与叶子结点(即数组头尾交换)然后直接删除交换后的叶子结点。创建一个AdjustDown函数,逐层下沉交换后的跟节点,保持仍然是一个堆。

void AdjustDown(HPDateType* a, int n, int parent)
{int child = parent * 2 + 1;while (child < n){if (child + 1 < n && a[child] > a[child + 1]){child++;}if (a[child] < a[parent]){Swap(&a[child], &a[parent]);parent = child;child = parent * 2 + 1;}else{break;}}
}
void HPPop(HP* php)
{assert(php);assert(php->size > 0);Swap(&php->a[0], &php->a[php->size - 1]);php->size--;AdjustDown(php->a, php->size, 0);
}

3.堆排序

主要思路:升序建大堆,降序建小堆

解释:以升序为例,创建一个大堆,即根节点为最大的数据,此时要排序,就直接将根节点与叶子结点交换(数组首尾交换),然后数组末尾的下标向前移动(此时数组末尾的数据不会参与后续运算),然后将交换后的跟节点使用AdjustDown函数下沉,以此类推,最后原数组就是一个升序排列。同理小堆也是如此。

为什么升序不用小堆呢,因为小堆每一次运算都要再次创建一个数组,浪费更多的内存,可以使用但是不推荐。同理这也是为什么降序使用小堆。

具体代码如下

void HeapSort(int* a, int n)
{// 降序,建小堆// 升序,建大堆for (int i = 1; i < n; i++){AdjustUp(a, i);}int end = n - 1;while (end > 0){Swap(&a[0], &a[end]);AdjustDown(a, end, 0);--end;}
}

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

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

相关文章

什么是最大路径?什么是极大路径?

最近学习中&#xff0c;在这两个概念上出现了混淆&#xff0c;导致了一些误解&#xff0c;在此厘清。 最大路径 在一个简单图G中&#xff0c;u、v之间的距离 d ( u , v ) min ⁡ { u 到 v 的最短路的长度 } d(u,v) \min \{ u到v的最短路的长度 \} d(u,v)min{u到v的最短路的…

wefaf

c语言中的小小白-CSDN博客c语言中的小小白关注算法,c,c语言,贪心算法,链表,mysql,动态规划,后端,线性回归,数据结构,排序算法领域.https://blog.csdn.net/bhbcdxb123?spm1001.2014.3001.5343 给大家分享一句我很喜欢我话&#xff1a; 知不足而奋进&#xff0c;望远山而前行&am…

每天Get一个小技巧:用DolphinScheduler实现隔几天调度

转载自tuoluzhe8521 这篇小短文将教会你如何使用Apache DolphinScheduler实现隔几天调度&#xff0c;有此需求的小伙伴学起来&#xff01; 1 场景分析 DolphinScheduler定时器模块-定时调度时每3秒|每3分钟|每3天这种定时&#xff0c;不能够跨分钟&#xff0c;跨小时&#x…

【C++】:string类的基本使用

目录 引言一&#xff0c;string类对象的常见构造二&#xff0c;string类对象的容量操作三&#xff0c;string类对象的访问及遍历操作四&#xff0c;string类对象的修改操作五&#xff0c;string类非成员函数六&#xff0c;整形与字符串的转换 引言 string 就是我们常说的"…

如何对SQL Server中的敏感数据进行加密解密?

为什么需要对敏感数据进行加密&#xff1f; 近几年有不少关于个人数据泄露的新闻&#xff08;个人数据通常包含如姓名、地址、身份证号码、财务信息等&#xff09;&#xff0c;给事发公司和被泄露人都带来了不小的影响。 许多国家和地区都出台了个人数据保护的法律法规&#…

Unity Animation--动画窗口指南(使用动画视图)

Unity Animation--动画窗口指南&#xff08;使用动画视图&#xff09; 使用动画视图 window -> Animation 即可打开窗口 查看GameObject上的动画 window -> Animation -> Animation 默认快捷键 Ctrl 6 动画属性列表 在下面的图像中&#xff0c;“动画”视图&am…

思科模拟器--2.静态路由和默认路由配置24.5.15

首先&#xff0c;创建三个路由器和两个个人电脑。 接着&#xff0c;配置两台电脑的IP&#xff0c;子网掩码和默认网关 对Router 0&#xff0c;进行以下命令&#xff1a; 对Router进行以下命令&#xff1a; 对Router2进行以下命令&#xff1a; 本实验完成。 验证&#xff1a;PC…

Vue3+ts(day06:路由)

学习源码可以看我的个人前端学习笔记 (github.com):qdxzw/frontlearningNotes 觉得有帮助的同学&#xff0c;可以点心心支持一下哈&#xff08;笔记是根据b站上学习的尚硅谷的前端视频【张天禹老师】&#xff0c;记录一下学习笔记&#xff0c;用于自己复盘&#xff0c;有需要学…

【ARMv8/v9 系统寄存器 5 -- ARMv8 Cache 控制寄存器 SCTRL_EL1 使用详细介绍】

关于ARM Cache 详细学习推荐专栏&#xff1a; 【ARM Cache 专栏】 【ARM ACE Bus 与 Cache 专栏】 文章目录 ARMv8/v9 Cache 设置寄存器ARMv8 指令 Cache 使能函数测试代码 ARMv8/v9 Cache 设置寄存器 关于寄存器SCTRL_EL1 的详细介绍见文章&#xff1a;【ARMv8/v9 异常模型入…

西南大学计算机考研,选学硕还是专硕?西南大学计算机考研考情分析!

西南大学&#xff08;Southwest University&#xff09;是教育部直属&#xff0c;教育部、农业农村部、重庆市共建的重点综合大学&#xff0c;是国家首批"双一流"建设高校&#xff0c;"211工程"和"985工程优势学科创新平台"建设高校。现任党委书…

【嵌入式大赛应用赛道】机械手臂

电机 进步电机&#xff1a;它的转动是以确定的步数进行的&#xff0c;只要计算好脉冲数量和频率&#xff0c;就可以准确预测和控制电机的转动角度、速度以及停止的位置 伺服电机&#xff1a;将输入的电信号&#xff08;如电压或电流指令&#xff09;转换成轴上的精确旋转运动…

大模型算法(一):从Transformer到ViT再到LLaMA

单任务/单领域模型 深度学习最早的研究集中在针对单个领域或者单个任务设计相应的模型。 对于CV计算机视觉领域&#xff0c;最常用的模型是CNN卷积模型。其中针对计算机视觉中的不同具体任务例如分类任务&#xff0c;目标检测任务&#xff0c;图像分割任务&#xff0c;以CNN作…

【传知代码】VRT: 关于视频修复的模型(论文复现)

前言&#xff1a;随着数字媒体技术的普及&#xff0c;制作和传播视频内容变得日益普遍。但是&#xff0c;视频中由于多种因素&#xff0c;例如传输、存储和录制设备等&#xff0c;经常出现质量上的问题&#xff0c;如图像模糊、噪声干扰和低清晰度等。这类问题对用户的体验和观…

几个排序器的verilog及其资源占用、延时分析

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 前言 因为课题需要&#xff0c;调研了几个快速排序方法&#xff0c;并手写或者改进了若干待测试对象&#xff0c;包括记分板型冒泡排序&#xff08;这个是别人的&#xff09…

树莓派|I2C通信

什么是I2C通信 I2C&#xff08;Inter-Integrated Circuit&#xff09;是一种串行通信协议&#xff0c;用于在集成电路(IC)之间传输数据。它由飞利浦公司&#xff08;现在的恩智浦半导体公司&#xff09;在20世纪80年代开发&#xff0c;并且成为了广泛应用于各种电子设备中的通…

【35分钟掌握金融风控策略28】贷中模型体系策略应用

目录 贷中模型体系策略应用 信用模型体系和模型在策略中的应用 反欺诈模型体系和模型在策略中的应用 运营模型体系和模型在策略中的应用 贷中模型体系策略应用 在贷前模型部分已经讲过&#xff0c;贷前开发的很多模型是可以在贷中直接使用的。贷中与贷前的不同点在于&…

ubuntu升级python

添加Python官方PPA源 sudo add-apt-repository ppa:deadsnakes/ppa 执行会显示各个版本ubuntu可以安装哪些python版本 更新软件包索引 sudo apt update 安装需要版本Python sudo apt install python3.11 检查Python版本: which python11 /usr/bin/python3.11 设置为系统默认Pyt…

STK中的光照计算模型

本文简要阐述STK中光照计算的模型。 在航天任务中&#xff0c;通常需要分析地面站、飞行器在一定时间内的光照情况&#xff0c;具体包括&#xff1a; 地面站处在光照区和阴影区的具体时间范围&#xff1b;考虑地形遮挡后&#xff0c;地面站的光照区和阴影区的变化情况&#x…

985大学电子信息专硕,考C语言+数据结构!中央民族大学25计算机考研考情分析!

中央民族大学&#xff08;Minzu University of China&#xff09;坐落于北京市学府林立的海淀区&#xff0c;南邻国家图书馆&#xff0c;北依中关村科技园&#xff0c;校园环境典雅&#xff0c;古朴幽美&#xff0c;人文氛围浓郁&#xff0c;具有鲜明的民族特色。由北京市、国家…

Google Ads谷歌广告账户被封停怎么办?

跨境出海业务少不了需要做Google Ads推广业务&#xff1b;其中让投手们闻风丧胆的消息就是帐户被暂停。当 Google 检测到任何违反其政策且可能损害用户在线体验的行为时&#xff0c;就会发生这种情况。那么如何在做广告推广的同时&#xff0c;保证账号不被封禁呢&#xff1f;看…