【C语音 || 数据结构】二叉树--堆

news2024/11/27 7:28:02

文章目录

    • 前言
        • 1.1 二叉树的概念
        • 1.2 满二叉树和完美二叉树
        • 1.3 堆的概念
        • 1.4 堆的性质
        • 1.4 堆的实现
          • 1.4.1堆的向上调整算法
          • 1.4.1堆的向下调整算法
          • 1.4.1堆的接口实现
          • 1.4.1.1堆的初始化
          • 1.4.1.2堆的销毁
          • 1.4.1.3堆的插入
          • 1.4.1.4堆的删除
          • 1.4.1.4堆的判空
          • 1.4.1.4 获取堆的数据个数

前言

二叉树是一种重要的数据结构,其中每个节点最多有两个子节点:左子节点和右子节点。它常用于实现搜索算法、排序算法、数据存储和图形表示等。二叉树具有递归性,可以通过遍历算法(如前序、中序、后序和层次遍历)来访问其节点。学习和理解二叉树对于掌握更复杂的数据结构和算法至关重要。

1.1 二叉树的概念

二叉树(Binary Tree)是一种特殊的树形数据结构,它的每个节点最多有两个子节点,通常被称为左子节点和右子节点,二叉树的子树有左右之分,其次序不能任意颠倒。

  1. 根节点(Root Node):二叉树的起始节点,它没有父节点,但可能有左子节点和右子节点。
  2. 父节点(Parent Node):对于每个节点(除根节点之外的节点),都有父节点,是一个具有子节点的节点。
  3. 左子节点(Left Child):对于每个节点,其左下方的节点称为其左子节点。
  4. 右子节点(Right Child):对于每个节点,其右下方的节点称为其右子节点。
  5. 叶子节点(Leaf Node):没有子节点的节点称为叶子节点。
  6. 非叶子节点(Non-Leaf Node):除了叶子节点以外的节点都称为非叶子节点。
  7. (Degree):节点的度是指该节点的子节点数量。在二叉树中,节点的度最大为2。
  8. 深度(Depth):从根节点到最远叶子节点的最长路径上的节点数称为二叉树的深度。
  9. 高度(Height):对于任意节点n,n的高度为从n到一片树叶的最长路径上的节点数。所有树叶的高度为0,根节点的高度就是树的高度。
1.2 满二叉树和完美二叉树

满二叉树(Full Binary Tree):除了叶子节点外,每一个节点都有左右两个子节点的二叉树称为满二叉树。

完全二叉树(Complete BinaryTree):完全二叉树从根结点到倒数第二层满足完美二叉树,最后一层可以不完全填充,其叶子结点必须靠左对齐,且不能有短,最后一层最少可以只有一个。

这不是一个完美二叉树
在这里插入图片描述

1.3 堆的概念

(Heap)是计算机科学中一类特殊的数据结构的统称。堆通常是一个可以被看做一棵 完全二叉树的 数组对象。 堆是非线性数据结构,相当于一维数组,有两个直接后继。

  • 大堆:父节点一定比子节点大,但是兄弟节点之间,不存在大小关系,堆的根节点是整个堆中最大的数
  • 小堆:父节点一定比子节点小,但是兄弟节点之间,不存在大小关系,堆的根节点是整个堆中最小的数

堆的父亲节点的下标和子节点的下标可以进行相互运算:

  • Parent = (Chlid - 1) / 2
  • Chlid = Parent / 2 - 1
1.4 堆的性质
  • 完美二叉树构成。

大堆:
在这里插入图片描述
小堆:
在这里插入图片描述

1.4 堆的实现
1.4.1堆的向上调整算法

给定一个数组,且这个堆是一个小堆,逻辑上看作是一种完美二叉树,需要传两个参数,一个数组,一个就是插入位置的节点在数组中的下标

  • 在数组的最后插入数据,开始进行向上调整算法。
  • 如果这个节点小于他的父亲节点,那就进行交换。
  • 如果这个节点大于他的父亲节点,那就结束向上调整。

这里给一组数据进行交换

int a[] = {10,15,56,25,30,70,5};

在这里插入图片描述
堆的向上调整算法代码实现:

void Swap(HPDataType* x,HPDataType* y)
{
	HPDataType tmp = *x;
	*x = *y;
	*y = tmp;
}
void AdjustUp(HPDataType* a, int child)
{
	int Parent = (child- 1) / 2;
	while (child> 0)
	{
		if (a[Parent] > a[child])
		{
			Swap(&a[Parent], &a[child]);
			child = Parent;
			Parent = (child - 1) / 2;
		}
		else
		{
			break;
		}
	}
}
1.4.1堆的向下调整算法

给定一个数组,且这个堆是一个小堆,逻辑上看作是一种完美二叉树。然后我们从根节点开始向下调整,向下调整算法有一个前提:左右子树必须是一个堆,才能进行调整。然后计算出这个根节点的两个孩子节点,进行比较,哪个小,让其与根节点进行比较。这里需要传三个参数,第一个数组,第二个是数组的个数,第三个是根节点的下标

  • 如果根节点大于孩子节点,那就进行交换。
  • 如果根节点小于孩子节点,就停止交换。

这里给一组数据进行交换

int a[]= {}

在这里插入图片描述
堆的向下调整算法代码实现:

void Swap(HPDataType* x,HPDataType* y)
{
	HPDataType tmp = *x;
	*x = *y;
	*y = tmp;
}
void AdjustDown(HPDataType* a, int n, int Parent)
{
	// 这里可以使用假设法
	int child = Parent * 2 + 1;
	while (child < n)
	{
		// 假设法这个位置需要进行判断是否是小的哪个孩子,不是则需要进行更新
		if (a[child] > a[child + 1] && child + 1 < n)
		{
			child += 1;
		}
		if (a[Parent] > a[child])
		{
			Swap(&a[Parent], &a[child]);
			Parent = child;
			child = Parent * 2 + 1;
		}
		else
		{
			break;
		}
	}
}
1.4.1堆的接口实现
  • 堆的初始化(HeapInit):用于初始化堆结构,为堆的后续操作做好准备。
  • 堆的销毁(HeapDestroy):释放堆占用的资源,通常涉及删除堆中的所有元素和释放内存。
  • 堆的插入(HeapPush):向堆中插入一个新元素,并保持堆的性质(大堆或小堆)。
  • 堆的删除(HeapPop):删除堆顶数据,将堆顶数据和堆尾数据进行交换,并保持堆的性质(大堆或小堆)。
  • 获取堆顶数据(HeapTop):获取堆顶数据。
  • 堆的判空(HeapEmpty):判断堆是否是空。
  • 堆的数据个数(HeapSize):计算堆中的数据个数。
1.4.1.1堆的初始化

对于堆的这个结构体来说,可以给_a开空间,也可以不开,一会儿进行push的时候,会进行判断,所以就可以制空,以防止成为野指针。对于size,可以给-1,这样就刚刚好和下标对上了。

typedef int HPDataType;
typedef struct Heap
{
	HPDataType* _a;
	int _size;    // 堆顶的下一个位置的下标
	int _capacity;// 堆的空间
}Heap;
// 堆的初始化
void HeapInit(Heap* hp)
{
	assert(hp);

	hp->_a = NULL;
	hp->_capacity = hp->_size = 0;
}

1.4.1.2堆的销毁
void HeapDestroy(Heap* php)
{
	assert(php);
	free(php->_a);
	php->_a = NULL;
	php->_size = php->_capacity = 0;
}
1.4.1.3堆的插入

这里插入数据,需要插入到这个数组的最后一个位置,然后进行向上调整算法,让他始终保持这个小堆(大堆)。

void HeapPush(Heap* php,HPDataType x)
{
	assert(php);
	if (php->_capacity == php->_size)
	{
		int newcapacity = php->_capacity == 0 ? 4 : php->_capacity * 2;
		HPDataType* new_a = (HPDataType*)realloc(php->_a,newcapacity*sizeof(HPDataType));
		if (new_a == NULL)
		{
			perror("HeapPush()::realloc() fail!!");
			return;
		}
		php->_capacity = newcapacity ;
		php->_a = new_a;
	}
	php->_a[php->_size++] = x;
	AdjustUp(php->_a, hp->_size - 1);
}
1.4.1.4堆的删除

需要将堆中最后一个节点于整个堆的根节点进行交换,交换完成之后,直接删除最后一个下标的位置,在进行向下调整。

void HeapPop(Heap* php)
{
	assert(php && php->_size > 0);
	Swap(&php->_a[0],&php->_a[php->_size - 1]);
	php->_size--;
	AdjustDown(php->_a, php->_size, 0);
}
1.4.1.4堆的判空

因为结构体中的size就是用来记录堆的数据个数的,所以可以直接判断这个数是否等于0。

int HeapEmpty(Heap* php)
{
	assert(php);
	 return php->_size == 0;
}
1.4.1.4 获取堆的数据个数

结构体中的size就是用来计数的,所以会方便很多

void HeapSize(Heap* php)
{
	assert(php);
	return php->_size;
}

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

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

相关文章

当客户一上来就问你产品价格,你可以多尝试问问

做外贸业务&#xff0c;每个对产品不了解的客户&#xff0c;很多人一上来都会习惯性地问我们价格。一些新手业务会比较直接&#xff0c;一下子就把价格报出去了&#xff0c;很容易因为报错价格导致客户杳无音讯。 其实这个时候&#xff0c;我们最应该做的是尝试跟客户多聊一聊…

vuInhub靶场实战系列--Kioptrix Level #4

免责声明 本文档仅供学习和研究使用,请勿使用文中的技术源码用于非法用途,任何人造成的任何负面影响,与本人无关。 目录 免责声明前言一、环境配置1.1 靶场信息1.2 靶场配置 二、信息收集2.1 主机发现2.1.1 netdiscover2.1.2 arp-scan主机扫描 2.2 端口扫描2.3 指纹识别2.4 目…

MySQL-子查询(DQL 结束)

054-where后面使用子查询 什么是子查询 select语句中嵌套select语句就叫做子查询。select语句可以嵌套在哪里&#xff1f; where后面、from后面、select后面都是可以的。 select ..(select).. from ..(select).. where ..(select)..where后面使用子查询 案例&#xff1a;找…

国际贸易条件简称的解析说明

声明&#xff1a;本文仅代表作者观点和立场&#xff0c;不代表任何公司&#xff01;仅用于SAP软件应用学习参考。 SAP创建销售订单的界面有个国际贸易条件的字段&#xff0c;这个字段选择值主要有如下选择值&#xff0c;国际贸易条件简称的具体解析说明如下&#xff1a; EXW &…

【文档智能】包含段落的开源的中文版面分析模型

github&#xff1a;https://github.com/360AILAB-NLP/360LayoutAnalysis 权重下载地址&#xff1a;https://huggingface.co/qihoo360/360LayoutAnalysis 一、背景 在当今数字化时代&#xff0c;文档版式分析是信息提取和文档理解的关键步骤之一。文档版式分析&#xff0c;也…

数据价值管理-数据验收标准

前情提要&#xff1a;数据价值管理是指通过一系列管理策略和技术手段&#xff0c;帮助企业把庞大的、无序的、低价值的数据资源转变为高价值密度的数据资产的过程&#xff0c;即数据治理和价值变现。第一讲介绍了业务架构设计的基本逻辑和思路。前面我们讲完了数据资产建设标准…

零售业上云为什么首选谷歌云

零售业是国民经济的重要组成部分&#xff0c;在促进经济发展、改善人民生活水平方面发挥着重要作用。零售业也是一个竞争激烈的行业&#xff0c;零售企业需要不断创新经营方式、提高服务质量才能在竞争中立于不败之地。 近年来&#xff0c;中国企业在品牌出海方面&#xff0c;一…

大模型 - Langchain-Chatchat小白本地部署踩坑血泪史

环境介绍 windows 11python 3.9.9显卡 GTX970 4G显存 &#xff08;可怜巴巴&#xff09;内存 24G 一、下载 Langchain-Chatchat 注意&#xff1a;这里先不要执行依赖下载&#xff0c;如果项目是通过 PyCharm 打开&#xff0c;就不要着急下载依赖&#xff0c;跟着往下面走&am…

算法第六天:力扣第977题有序数组的平方

一、977.有序数组的平方的链接与题目描述 977. 有序数组的平方的链接如下所示&#xff1a;https://leetcode.cn/problems/squares-of-a-sorted-array/description/https://leetcode.cn/problems/squares-of-a-sorted-array/description/ 给你一个按 非递减顺序 排序的整数数组…

【Qt 学习笔记】Qt窗口 | 标准对话框 | 输入对话框QInputDialog

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;Qt 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ Qt窗口 | 标准对话框 | 输入对话框QInputDialog 文章编号&#xff1a;…

vue3+electron搭建桌面软件

vue3electron开发桌面软件 最近有个小项目, 客户希望像打开 网易云音乐 那么简单的运行起来系统. 前端用 Vue 会比较快一些, 因此决定使用 electron 结合 Vue3 的方式来完成该项目. 然而, 在实施过程中发现没有完整的博客能够记录从创建到打包的流程, 摸索一番之后, 随即梳理…

图的遍历介绍

概念 特点 无论是进行哪种遍历&#xff0c;均需要通过设置辅助数组标记顶点是否被访问来避免重复访问&#xff01;&#xff01;&#xff01;&#xff01; 类型 深度优先遍历 可以实现一次遍历访问一个连通图中的所有顶点&#xff0c;只要连通就能继续向下访问。 因此&#x…

getDay 与 getUTCDay 本质区别

背景 我在做这个实验的时候是北京时间&#xff1a;2024年6月12日 下午16&#xff1a;32分许 研究方向 本文探讨 getDay 与 getUTCDay 本质区别 测试用例 如果你现在的时区设置的是 &#xff08;UTC08:00&#xff09; 北京&#xff0c;重庆&#xff0c;香港特别行政区&#x…

二刷算法训练营Day29 | 回溯算法(5/6)

目录 详细布置&#xff1a; 1. 491. 非递减子序列 2. 46. 全排列 3. 47. 全排列 II 详细布置&#xff1a; 1. 491. 非递减子序列 给你一个整数数组 nums &#xff0c;找出并返回所有该数组中不同的递增子序列&#xff0c;递增子序列中 至少有两个元素 。你可以按 任意顺序…

智能盒子如何检测进气压力传感器?

进气压力传感器是一种用于测量发动机进气系统中压力的传感器。安装在发动机的进气管路或进气歧管上&#xff0c;用于监测进气压力的变化。进气压力传感器的作用是将测量到的压力信号转换为电信号&#xff0c;以便发动机控制单元(ECU)可以根据压力变化来调整燃油喷射量、点火时机…

[ue5]建模场景学习笔记(6)——必修内容可交互的地形,交互沙(4)

1.需求分析&#xff1a; 现在我们已经有了可以在世界内近于无限的跑动痕迹&#xff0c;现在需要对痕迹进行细化&#xff0c;包括例如当人物跳起时便不再绘制痕迹&#xff0c;以及痕迹应该存在深浅&#xff0c;应该由两只脚分别绘制&#xff0c;同时也应该对地面材质进行进一步处…

优质短视频素材下载网站有哪些?分享优质短视频素材下载资源

在抖音等短视频平台上取得成功的关键之一是制作出具有视觉吸引力的内容。好的素材可以极大地提升视频的质量和观看体验&#xff0c;吸引更多观众。为了帮助抖音视频制作者找到优质的素材&#xff0c;这里详细介绍几个提供高清视频素材的下载网站。 蛙学府&#xff1a; 蛙学府是…

----几种接口的使用---

Compareable接口 对于给数组中的变量成员排序&#xff0c;我们能想到用sort&#xff0c;根据成员之间的大小进行排序&#xff0c;那么如果数组中的成员是对象的话&#xff0c;单单只是用sort去排序肯定是步成功的&#xff0c;因为并不知道要根据什么去排序&#xff0c; 这时要…

RNA-seq上下游分析snakemake流程

学习完snakemake后写的第一个流程是RNA-seq上游定量和下游的质控和差异分析。 使用fastp处理fastq文件&#xff0c;在使用START比对到基因组同时得到raw count&#xff0c;使用非冗余外显子长度作为基因的长度计算FPKM、TPM&#xff0c;同时也生成了CPM的结果。 非冗余外显子…

6.nginx负载均衡

说明 增加服务器的数量,将请求分发到各个服务器上。 将原来请求集中到单个服务器上的情况改为将请求分发到多个服务器上。 案例 浏览器请求地址http://ip/edu/a.html, 负载均衡的效果,平分到8080和8081两台服务上中。 准备工作 tomcat8080配置 tomcat8081配置 直接通过…