数据结构——堆(存储完全二叉树)

目录

一、堆的概念

二、堆的一些性质

三、堆的结构定义

四、堆的初始化

五、堆打印

六、向上调整算法

七、堆的插入

八、向下调整算法

九、堆的删除

十、取堆顶元素

十一、求堆大小

十二、堆判空

十三、测试代码


一、堆的概念

堆是一种顺序存储完全二叉树的数据结构。

二、堆的一些性质

堆分为小堆和大堆:

小堆要求父亲结点数据小于孩子结点;

大堆要求父亲结点数据小于孩子结点。

如何根据孩子结点下标找到父亲结点?

parent = (child - 1) / 2

如何根据父亲结点下标找到孩子结点?

child = 2 * parent + 1 (左孩子)

三、堆的结构定义

堆的结构中包含数组、堆大小、堆容量

//堆的结构定义
typedef int HPDataType;typedef struct Heap {HPDataType* a;int size;int capacity;
}HP;

四、堆的初始化

将数组初始化为空,堆大小和容量都初始化为0

//堆的初始化
void HPInit(HP* php)
{php->a = NULL;php->size = 0;php->capacity = 0;
}

五、堆打印

打印数组

//堆打印
void HPPrint(HP* php)
{assert(php);for (int i = 0; i < php->size; i++){printf("%d ", php->a[i]);}printf("\n");
}

六、向上调整算法

孩子结点与父亲结点比较,如果孩子结点小于父亲结点,就将孩子结点与父亲结点交换。

注意第二个循环条件:是 child > 0,为什么不是 parent >=0 呢?

因为parent最小是0,永远不会小于0。但是该代码也能跑,因为当parent为0时,重置下标时,child重置为0,而parent = (child - 1) / 2也重置为0,此时a[child] = a[parent],因此循环结束。

//向上调整算法
void AdjustUp(HPDataType*a, int child)
{int parent = (child - 1) / 2;while (a[child] < a[parent] && child > 0)//孩子结点比父亲结点小{//交换父亲结点和孩子结点的数据HPDataType tmp = a[child];a[child] = a[parent];a[parent] = tmp;//父亲结点和孩子结点下标重置child = parent;parent = (child - 1) / 2;}
}

七、堆的插入

插入数据前先检查堆容量是否足够,容量不够则扩容,容量足够则将数据存入数组中,再用向上调整算法将新插入的数据进行调整。

//堆的插入
void HPPush(HP* php, HPDataType x)
{assert(php);//堆扩容if (php->size ==php->capacity ){int newcapacity = php->capacity == 0 ? 4 : php->capacity * 2;HPDataType* tmp = (HPDataType*)realloc(php->a, sizeof(HPDataType) * newcapacity);if (tmp == NULL){perror("realloc fail");exit(-1);}php->a = tmp;php->capacity = newcapacity;}php->a[php->size++] = x;//向上调整算法AdjustUp(php->a, php->size - 1);
}

八、向下调整算法

将父亲结点与孩子结点比较,如果父亲结点大于孩子结点,则交换

由于可能有两个孩子结点,先要确认右孩子是否存在,如果存在取较小的孩子结点与父亲结点交换

//向下调整算法
void AdjustDown(HPDataType* a, int size, int parent)
{int child = parent * 2 + 1;while (child < size){if (child + 1 < size)//存在右孩子{if (a[child + 1] < a[child])//右孩子比左孩子小,用右孩子顶替父亲结点位置{child = child + 1;}}if (a[child] < a[parent]){//交换父亲结点与孩子结点HPDataType tmp = a[child];a[child] = a[parent];a[parent] = tmp;//重置父亲结点和孩子结点parent = child;child = parent * 2 + 1;}else{break;}}
}

九、堆的删除

堆的删除是删除堆顶元素,因为删除堆尾元素是没有意义的。

删除堆顶即删除二叉树的根,删除后还要使之成为一个完全二叉树,所以需要用次小值去顶替堆顶的位置。

具体方法:

先将堆尾元素与堆顶元素交换位置,然后删除堆尾元素,再利用向下调整算法将堆顶位置元素向下调整到合适的位置。

//堆的删除
void HPPop(HP* php)
{assert(php);assert(php->size);//空堆不可删除//交换堆顶元素和堆底元素HPDataType tmp = php->a[0];php->a[0] = php->a[php->size - 1];php->a[php->size - 1] = tmp;//删除堆底元素php->size--;//向下调整算法AdjustDown(php->a, php->size, 0);
}

十、取堆顶元素

先判断堆是否为空,不空则返回堆顶元素

//取堆顶元素
HPDataType HPTop(HP* php)
{assert(php);assert(php->size);return php->a[0];
}

十一、求堆大小

返回size即可

//求堆大小
size_t HPSize(HP* php)
{assert(php);return php->size;
}

十二、堆判空

利用size判断堆是否为空

//判空
bool HPEmpty(HP* php)
{assert(php);return php->size == 0;
}

十三、测试代码

void test01()
{//创建堆HP hp;//初始化堆HPInit(&hp);//堆插入HPPush(&hp, 1);HPPush(&hp, 5);HPPush(&hp, 3);HPPush(&hp, 6);HPPush(&hp, 7);HPPush(&hp, 5);HPPush(&hp, 4);HPPush(&hp, 9);HPPush(&hp, 8);//堆打印HPPrint(&hp);//堆插入HPPush(&hp, 1);//堆打印HPPrint(&hp);//堆删除HPPop(&hp);//堆打印HPPrint(&hp);//取堆顶元素printf("%d\n", HPTop(&hp));//求堆大小printf("%zd\n", HPSize(&hp));//堆判空if (HPEmpty(&hp))printf("空\n");elseprintf("非空\n");
}int main()
{test01();return 0;
}

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

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

相关文章

智能井盖传感器产品介绍,井盖传感器推荐

智能井盖传感器是一种先进的设备&#xff0c;能够提高城市管理的智能化水平。该传感器作为城市生命线建设的核心组成部分&#xff0c;为智慧城市的正常建设提供了有力的保障&#xff0c;能够提高城市管理的智能化水平。这种设备通过高度灵敏的传感器网络&#xff0c;实时监测井…

智能优化算法应用:基于野马算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于野马算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于野马算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.野马算法4.实验参数设定5.算法结果6.参考文献7.MATLAB…

通过Powershell远程控制windows服务器

1、被测服务器5985、5986端口开启&#xff0c;在网络设置中&#xff0c;点击“更改连接属性”。 2、网络配置文件中选择“专用”。 3、以管理员权限运行Powershell&#xff0c; 4.通过powershell命令在本地电脑上添加远端信任主机 winrm set winrm/config/client {TrustedHos…

字符串和哈希表的基本用法总结

2287. 重排字符形成目标字符串 解决代码 class Solution {public int rearrangeCharacters(String s, String target) {Map<Character, Integer> sCounts new HashMap<Character, Integer>();Map<Character, Integer> targetCounts new HashMap<Chara…

Vue.js深度解析:前端开发的生产力引擎

在数字时代&#xff0c;Web应用的用户界面(UI)不仅是功能的展示窗口&#xff0c;更是品牌形象的前哨站。为此&#xff0c;前端开发者不断寻求最佳解决方案&#xff0c;期望以最快的速度打造最吸引人的用户体验。Vue.js作为一个渐进式JavaScript框架&#xff0c;在不断演进的前端…

关于DWC OTG2.0中PFC的理解

在DWC OTG2.0 Controller手册中&#xff0c;有一章节专门介绍了PFC&#xff0c;Packet FIFO Controller。其内部分为共享FIFO&#xff08;shared FIFO&#xff09;以及专用FIFO&#xff08;Dedicated FIFO&#xff09;&#xff0c;并针对dev和host两种模式&#xff0c;并且还要…

数据库基础语法

●SQL SELECT 用法 ●SQL SELECT DISTINCT 用法 ●SQL WHERE用法 ●SQL AND & OR用法 ●SQL ORDER BY用法 ●SQL INSERT INTO用法 ●SQL UPDATE用法 ●SQL DELETE用法 前言 数据库快速入门&#xff0c;熟悉基础语法 一、SQL 是什么&#xff1f; 存储数据库 二、…

国内AI翘楚,看看有没有你心动的offer?

科技创新争占高地&#xff0c;AI领域各显神通。从一战成名的阿尔法狗到引起轩然大波的ChatGPT&#xff0c;我们早已卷入了一场没有硝烟的革命。前方世人看到的科技日新日异、岁月静好&#xff0c;后方是各大企业的绞尽脑汁、争先恐后。人工智能时代&#xff0c;AI是挡不住的时代…

学习mysql记录

环境: macbookpro m1 1. 安装mysql 使用苹果自带的包管理工具brew进行安装 1. brew install mysql (安装) 2. brew services start mysql (启动mysql服务) 1.1 如果提示zsh: mysql command not found, 终端执行以下命令 1. cd ~ (切到根目录) 2. vi .bash_profile (进入编辑…

梦想与魔法:编程之路的挑战与荣耀

在年少轻狂的岁月里&#xff0c;我们都有过一些不切实际的梦想&#xff0c;渴望成为某种神奇的存在。我的梦想是成为一名神奇的码农&#xff0c;用键盘编织魔法&#xff0c;创造出炫酷的虚拟世界。然而&#xff0c;现实是残酷的&#xff0c;当我刚入门计算机领域时&#xff0c;…

QxOrm 如何自定义主键?

默认情况下QxOrm的主键是long类型自增的&#xff0c;但是有时候我们不想使用这个主键&#xff0c;想使用比如string类型的主键。 可以使用QX_REGISTER_PRIMARY_KEY宏定义另一种类型&#xff08;例如&#xff0c;QString 类型&#xff09;的唯一 id&#xff08;主键&#xff09…

分块板子题

区间加法&#xff0c;区间求和 #include <bits/stdc.h> using namespace std; using ll long long; const int N 1e6 10; #define int long long ll s[N], b[N], w[N], add[N]; ll l[N], r[N], belong[N]; ll len, tot, n, q;inline void init() {len sqrt(n), tot …

1.5 常用DCC软件

一、DCC软件的定义 所谓DCC&#xff0c;就是Digital Content Creation的缩写&#xff0c;即数字内容创作。DCC的范围包括二维/三维、音频/视频编辑合成、动态/互动内容创作、图像编辑等。 二、常用建模软件 3DS MAX 擅长&#xff1a;硬表面建模、静态物体建模。&#xff08;国…

nextTick

在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法&#xff0c;获取更新后的 DOM。 // 修改数据 vm.msg Hello // DOM 还没有更新 Vue.nextTick(function () {// DOM 更新了 })切换页签&#xff0c;不流畅&#xff0c;所以用nextTick&#xff0c;等页…

要求CHATGPT高质量回答的艺术:提示工程技术的完整指南—第 17 章:对话提示

要求CHATGPT高质量回答的艺术&#xff1a;提示工程技术的完整指南—第 17 章&#xff1a;对话提示 对话提示是一种允许模型生成模拟两个或多个实体之间对话的文本的技术。 通过向模型提供上下文和一组角色或实体&#xff0c;以及他们的角色和背景&#xff0c;并要求模型生成他…

视频相似度对比 python opencv sift flann

提取SIFT特征的代码&#xff0c;返回关键点kp及特征描述符des def SIFT(frame):# 创建SIFT特征提取器sift cv2.xfeatures2d.SIFT_create()# 提取SIFT特征kp, des sift.detectAndCompute(frame, None)return kp, des 这行代码是使用SIFT&#xff08;Scale-Invariant Feature…

扔掉sql语句,用 QxOrm 让你的数据库操作从来没有这么简单过!

ORM简介&#xff1a; ORM 全称是 Object Relational Mapping&#xff08;对象关系映射&#xff09;&#xff0c;是一种程序设计技术&#xff0c;用于实现面向对象编程语言里不同类型系统的数据之间的转换。从效果上说&#xff0c;它其实是创建了一个可在编程语言里使用的“虚拟…

Java 新特性探索:从 JDK9 到 JDK17 的关键改进与示例代码

JDK 新特性 JDK9 jshell 交互式工具 引入了一个交互式的编程工具&#xff0c;可以在命令行中(cmd)直接执行和测试 Java 代码片段。 // 示例1&#xff1a;在jshell中执行简单的Java代码 jshell> int a 10; a > 10jshell> int b 20; b > 20jshell> int sum …

基于ssm人事管理信息系统论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本人事管理信息系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息…

JPA与MySQL锁实战

前言&#xff1a;最近使用jpa和mysql时&#xff0c;遇到了死锁问题。在解决后将一些排查过程中新学到和复习到的知识点再总结整理一下。首先对InnoDB中锁相关的概念进行介绍&#xff0c;然后展示如何利用JPA提供的排他锁来实现想要的功能&#xff0c;最后对死锁问题进行讨论。 …