C语言二叉树与建堆

C语言堆数据结构实现:从核心算法到堆排序与TOPK应用 在数据结构与算法领域,堆是一种基于完全二叉树实现的高效数据结构,其核心在于维护父节点与子节点间的特定大小关系,分为大根堆和小根堆。其原理是通过数组存储,利用下标计算公式实现快速父子节点访问,并通过上滤与下滤操作在O(log N)时间内维护堆性质。这种结构的技术价值在于提供了优先级队列的高效实现,支持快速获取最值及动态插入删除。应用场景广泛,包括操作系统任务调度、数据流处理及高性能计算。本文以C语言为例,深入剖析堆排序与TOPK问题这两种经典应用,其中堆排序通过原址调整实现O(N log N)排序,而TOPK 阅读详情

 

目录

二叉树有关概念

二叉树有关计算公式

二叉树的创建

二叉树的初始化

二叉树的销毁

二叉树的插入

二叉树的删除

判断二叉树是否为空以及二叉树元素个数

 建堆


二叉树有关概念

二叉树:二叉树是每个节点最多有两个子树的树结构。

节点度:一个节点含有的子树的个数。

兄弟节点:具有相同父节点的节点互称为兄弟节点。

叶子节点或终端节点:没有任何子节点的节点称为叶子节点。

父节点、子节点:如果一个节点下面连接多个节点,那么该节点称为父节点,它下面的节点称为子 节点。

树的度:所有结点的度数的最大值。二叉树的度小于等于2。

树的深度:从根节点开始(其深度为0)自顶向下逐层累加的。

树的高度:从叶子节点开始(其高度为0)自底向上逐层累加的。

根节点:一棵树最上面的节点称为根节点。

节点的祖先:从根到该节点所经分支上的所有节点。

森林:由m棵互不相交的树组成的集合。

二叉树有关计算公式

1.n个节点的二叉树一共有((2n)!)/(n! * (n+1)!)种
2.n层二叉树的第n层最多为2^(n-1)个
3.二叉树节点计算公式 N = n0+n1+n2,度为0的叶子节点比度为2的节点数多一个。N=1*n1+2*n2+1
4.具有n个节点的完全二叉树的深度为log2(n) + 1
5. 树的高度:从根节点到所有叶节点中最大的边的数目。树的深度:从根节点到所有叶节点中最多的节点数目。
下面是计算父子间关系(重点)

leftchild=parent*2+1

rightchild=parent*2+2

parent=(child-1)/2

接下来是如何创建二叉树

二叉树的创建

typedef int HPDataType;

typedef struct Heap
{
	HPDataType* a;
	int size;
	int capacity;
}HP;

二叉树的初始化

void HeapInit(HP* php)
{
	php->a = NULL;
	php->size = php->capacity = 0;
}

二叉树的销毁

void HeapDestroy(HP* php)
{
	assert(php);
	free(php->a);
	php->a = NULL;
	php->size = php->capacity = 0;
}

二叉树的插入

void swap(HPDataType* a, HPDataType* b)
{
	HPDataType as = *a;
	*a = *b;
	*b = as;
}
void AdjustUpd(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;
		}
	}
}

void HeapPush(HP* php, HPDataType x)
{
	assert(php);
	if (php->size == php->capacity)
	{
		int newca = php->capacity == 0 ? 4 : php->capacity * 2;
		HPDataType* newhp = (HPDataType*)realloc(php->a, newca*sizeof(HPDataType));
		if (newhp == NULL)
		{
			perror("realloc");
			exit(-1);
		}
		php->a = newhp;
		php->capacity = newca;
	}
	php->a[php->size] = x;
	php->size++;
	AdjustUpd(php->a, php->size-1);
}

二叉树的删除

void HeapPop(HP* php)
{
	assert(php);
	if (HeapEmpty(php))
	{
		return;
	}
	php->a[0] = php->a[php->size - 1];
	php->size--;
	AdjustDownd(php->a,php->size,0);
}

判断二叉树是否为空以及二叉树元素个数

bool HeapEmpty(HP* php)
{
	return php->size == 0;
}
int HeapSize(HP* php)
{
	assert(php);
	return php->size ;
}

 建堆

//小堆
void AdjustDown1(HPDataType* a, int size, int parent)
{
	int child = parent * 2 + 1;
	while (child < size)
	{
		if (child+1 < size && a[child + 1] < a[child])
		{
			child++;
		}
		if (a[child] < a[parent])
		{
			swap(&a[child], &a[parent]);
			parent = child;
			child = parent *2 +1;
		}
		else
			break;
	}
}
//大堆
void AdjustDownd(HPDataType* a, int size, int parent)
{
	int child = parent * 2 + 1;
	while (child < size)
	{
		if (child + 1 < size && a[child + 1] > a[child])
		{
			child++;
		}
		if (a[child] > a[parent])
		{
			swap(&a[child], &a[parent]);
			parent = child;
			child = parent *2 +1;
		}
		else
			break;
	}
}


 这里分别是建大堆与小堆的代码

电压电流双闭环PFC单相PWM整流 电压电流双闭环PFC单相整流。仿真及代码 阅读详情

相关推荐

Android逆向进阶篇 Charles + Drony Vpn绕过代理检测方案 获取猫眼App数据

Android逆向进阶篇 Charles + Drony Vpn绕过代理检测方案 获取猫眼App数据

曾用名:极客柒 1852

数据结构初阶(C语言)-二叉树-顺序表建堆

int size;}HP;由于堆在本质上是基于顺序表结构去实现的,所以接下来我们所介绍的实现内容重点介绍与顺序表的不同的地方,相同部分则直接给出代码。

xiuwoaiailixiya的博客 1436

海康H304NAS 刷机飞牛

本文旨在分享如何将闲置的海康威视H304 NAS刷入飞牛NAS系统,并利用iStoreOS作为安装媒介。之前因为使用极空间NAS,这台H304闲置已久。最近尝试了飞牛NAS,在虚拟机上安装后挂载极空间的电影资源,体验不错,于是决定重新折腾这台H304。我个人喜欢尝试新系统,之前经常更新H304的固件,但设备总在使用一两年后出现故障,需要联系技术清理日志才能恢复。最后一次设备“变砖”后,连技术人员也联系不上了,自己尝试修复未果,设备就此闲置两三年。

u012985257的博客 2747

07.【数据结构-C语言】二叉树-堆-顺序结构(树、二叉树、堆的概念,堆实现,向上调整&向下调整,建堆时间复杂度,堆的应用:堆排序、TOP-K问题)

本文系统介绍了树和二叉树数据结构及堆的实现与应用。主要内容包括:1)树的基本概念、术语(如度、深度、祖先等)和存储表示方法;2)二叉树的定义、特性(度≤2、有序性)和性质(如节点数公式n0=n2+1);3)堆的实现与应用,重点讲解了堆的向上/向下调整算法、插入删除操作及时间复杂度分析;4)堆在排序(堆排序)和TOP-K问题中的实际应用,提供了完整的代码实现。文章通过数学证明和示例代码,详细阐述了这些重要数据结构的概念原理和具体实现方法。

恢弘志士之气,不宜妄自菲薄 1039

对计算机专业来说学历真的重要吗?

我本科学校是渣渣二本,研究生学校是985,现在毕业五年,校招笔试、面试,社招面试参加了两年了,就我个人的经历来说下这个问题。 这篇文章很长,但绝对是精华,相信我,读完以后,你会知道学历不好的解决方案,记得帮我点赞哦。 先说结论,无论赞不赞同,它本质就是这样:对于技术类工作而言,学历五年以内非常重要,但有办法弥补。五年以后,不重要。 目录: 张雪峰讲述的事实 我看到的事实 为什么会这样 ...

启舰 55万+

LaTeX新手入门以及TeXlive和TeXstudio的安装使用

作为一个新手,LaTeX的了解和使用很是费了一番功夫,因此,在这里给找不到路的同志们稍微介绍一下。如有错误,敬请指正。本篇内容基于Win10系统,因此安装在Mac或者Linux上的同学可以再找找其他的介绍文章。 目录 LaTeX介绍 LaTeX环境配置 一、TeXlive下载 二、TeXlive安装 1. 安装main installer 2. 正式安装 三、TeXstudio安装...

zywhehe的博客 21万+

特殊的二叉树:堆

二叉树由一个一个节点构成,基本单位是根、左子树和右子树,节点间的基本关系是父节点和子结点(父和子是相对的),如下图:没有节点的树称为空树对于有节点的树,有两个特殊情况---完全二叉树和满二叉树没有父节点(最顶层)的节点叫做根节点没有分支节点的节点叫做叶子节点一个节点所具有的分支节点(子节点)数叫做度二叉树的层数叫做深度同一层的节点间没有父子关系一个节点至多有两个分支节点(子节点)堆的底层使用数组实现,所以可以像顺序表那样定义结构,如下int size;}binary;

ha2042894194的博客 817

【电驱动】永磁同步电机工作原理及分类

永磁同步电机工作原理及分类

星Yeah 的博客 7326

堆与堆排序

堆与堆排序的说明与实现

dasdasfv的博客 1208

10、基于单倍型多样性隐马尔可夫模型的基因型错误检测

本文提出了一种基于单倍型多样性隐马尔可夫模型(HMM)的基因型错误检测方法,旨在提升三人组基因型数据中错误识别的准确性。通过利用群体水平的连锁信息,该方法克服了传统方法在小系谱数据中表现不佳的局限性。文章详细介绍了模型结构、三种替代似然函数及其计算方法,并通过模拟数据集和真实数据集验证了方法的有效性。实验结果显示,该方法在灵敏度、特异度和准确率方面均表现出色,为基因数据质量控制提供了新的解决方案。

moon9的博客 96

Proteus-51单片机-LCD1602显示DS1302时钟

本文详细介绍了如何使用Proteus仿真51单片机配合LCD1602显示DS1302时钟的步骤,包括DS1302时钟芯片的主要特性、引脚定义、外围电路以及LCD1602的原理和技术参数。此外,还讲解了LCD1602的指令集和显示字符的方法,并给出了初始化及显示操作的步骤。

让你爱上电路设计 6980

C语言堆笔记

3. 建堆(建堆是基于已有数组,将数组逻辑上视为完全二叉树来调整结构,满足堆的性质,不需要额外空间“连接”数组,仅通过下标关系操作节点)n-1为最后一个数据的索引,n-1-1即算父子数索引的公式的。方法2:向下调整建堆(从最后一个非叶子节点开始,向前调整)方法1:向上调整建堆(从第二个元素开始,逐个向上调整)// 2. 删除最后一个元素(原堆顶)(2)左子数i*2+1,右子数为i*2+2。// 1. 将堆顶与最后一个元素交换。// 从最后一个非叶子节点开始调整。· 从 (n-1-1)/2 开始倒序调整。

2502_94135489的博客 398

微信小程序 - 解决报错 {“errcode“:41002,“errmsg“:“appid missing, rid: X“} 微信报错错误码errcode“:41002问题分析及解决教程(详细排查)

【微信小程序】报错{“errcode“:41002,“errmsg“:“appid missing, rid: 64e55770-67c1fb7e-027c5a70“}:【微信小程序】微信小程序登录请求出现appid missing提示,微信公众号{"errcode":41002,"errmsg":"appid missing"},微信 报错{“errcode“:41002,“errmsg“:“appid missing,微信小程序获取openid返回appid missing的问题,微信小程序提示Erro

🏆 前端领域优质创作者 5655

堆的时间复杂度计算

解决堆排序的升降序以及基于堆的top K问题中出现的时间复杂度计算

m0_73975164的博客 1157

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

C语言-二叉树的相关算法

堆本质上是一棵完全二叉树,堆中某个结点的值总是不大于或不小于其父结点的值。排升序---建大堆 排降序---建小堆。层序遍历:一层一层的,需借助队列的先进先出。非完全二叉树按层序走,空节点后还有非空结点。完全二叉树按层序走,非空节点一定是连续的。向下调整的条件:左右子树都是大堆/小堆。前序遍历:根 左子树 右子树。中序遍历:左子树 根 右子树。后序遍历:左子树 右子树 根。物理结构:在内存中是如何存储的。时间复杂度:N*logN。逻辑结构:是想象出来的。

2401_89033666的博客 259

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

数据结构‑二叉树(二):二叉堆从零实现|Heap结构设计 + 建堆优化 + 堆排序深度解析

本文承接二叉树专题,深入解析数据结构中的核心结构——二叉堆。从完全二叉树的数组映射出发,结合C语言实现完整堆接口,详细讲解结构体设计、指针传参原因、向上调整与向下调整原理,以及大小根堆切换方法。通过图解对比向上建堆与向下建堆,分析O(NlogN)与O(N)复杂度差异,并深入拆解堆排序、“降序建小堆,升序建大堆”的核心思想。最后结合测试案例,总结Top-K、优先级队列等实际应用与常见踩坑。

Luminousone的博客 349

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

C++之堆排

data++是C语言中的一个表达式,它会将指针data指向的地址向后移动一个存储单位的距离,这里一个存储单位指的是数组的元素大小。如果data是一个数组名,则它代表数组的首元素的地址。i--)// n/2是找到最后一个叶子的父节点在树中的位置,当i=1时,就说明此时在根节点处,在树中根节点是从1开始的 并不是0。需要注意的是,由于data是一个指向数组的指针,当使用data++表达式时,会改变指针指向的位置,因此建议在代码中使用时要小心。最小堆:根节点的值最小,任意节点的值都小于等于其左右子节点的值。

m0_74892619的博客 438

【数据结构】C++语言实现二叉树的介绍及堆的实现(详细解读)

int size;}HP;

bhbcdxb123的博客 2230

DS初阶:二叉树的顺序结构及堆的实现

学会利用堆来实现堆排序和TOP-K问题

weixin_51142926的博客 8522

堆的实现以及利用堆进行排序

堆是一种特殊的完全二叉树,分为最大堆和最小堆。在最小堆中,父节点的值总是小于或等于其子节点的值。这种特性使得堆的根节点始终是所有节点中的最小值,非常适合实现优先队列。堆中某个结点的值总是不⼤于或不⼩于其⽗结点的值;堆总是⼀棵完全⼆叉树。⼆叉树性质对于具有 n 个结点的完全⼆叉树,如果按照从上⾄下从左⾄右的数组顺序对所有结点从0 开始编号,则对于序号为 i 的结点有:若 i>0 , i 位置结点的双亲序号: (i-1)/2;i=0 , i 为根结点编号,⽆双亲结点。

zzh_Zao的博客 1838

C语言堆和树 二叉树第一篇

int data;上面这种情况如果知道节点的度,那么可以这么定义的,如下图。左边情况就不行,右边这种情况是可以的 如果还要用这种方法使用有三个子节点,那么需要再加个child 3.第二种 顺序表存储孩子int data;

2501_91488717的博客 1087

堆排序C语言实现

1.堆,堆实际上是一棵完全二叉树,堆分为大顶堆和小顶堆。大顶堆需要满足性质:Key[i]>=Key[2i+1]&&key>=key[2i+2];小顶堆需要满足性质:Key[i]即任何一非叶节点的关键字不大于或者不小于其左右孩子节点的关键字。 2.堆排序一般分为三个过程: 建堆(初始化堆):从一个数组顺序读取元素,建立一个堆(完全二叉树) 调整堆:将堆进行调整,使得堆顶为最

夜空下划过的流星 886

C语言堆排序实战:从数组建堆到完整排序(附避坑指南)

本文深入解析C语言堆排序算法,从数组与二叉树的映射关系讲起,详细对比了向上调整与向下调整两种建堆方法的时间复杂度,并指出向下调整法(O(N))更优。文章提供了完整的升序/降序排序代码实现,强调了“升序建大堆,降序建小堆”的核心原则,并附有实用的避坑指南和边界条件处理,帮助开发者高效掌握这一稳定且空间效率高的排序算法。

mango的博客 169

【数据结构】堆的原理与C语言实现

本文系统介绍了堆数据结构及其应用。主要内容包括:1.堆的基本概念与性质,分为大根堆和小根堆;2.堆的实现方法,详细阐述了向下调整算法、堆创建、插入删除操作及完整代码实现;3.堆的两个重要应用场景:堆排序算法(包括升序和降序实现)和TOP-K问题解决方案。文章通过完整代码示例展示了堆的具体实现过程,并分析了其时间复杂度。堆作为一种高效的完全二叉树结构,在排序和优先级队列等场景中具有重要应用价值。

Z2382430464的博客 914

C语言堆以及堆排序

了解了思想之后我么来解决为什么排升序的时候建造大堆而不建造小堆,如果建小堆,每次只能拿到数组中的最小值,无法找到数组中的最大值也就意味着和最后一个元素交换后,无法的到升序的序列,而且还需要额外的空间来实现,效率低。堆的删除只有一点需要注意的是,我们如果直接删除堆顶元素的话,这会导致堆的结构被破坏,我们不希望只是删除一个元素就要去重建整个堆。需要注意的是,堆的物理上就是顺序表,删除堆顶的元素就是删除第一个元素,那么理所当然的需要移动剩下的数据,这里与顺序表也是一致的,那么顺序表如何删除效率高呢?

2302_77186349的博客 833

【数据结构】二叉树——堆如何实现

二叉树的顺序结构;堆的概念及结构;堆向下调整的算法;堆的代码实现;堆排序;TOP-K问题

m0_57388581的博客 3888
上一篇: C语言队列
下一篇: 十大排序算法详解(一)冒泡排序、选择排序、插入排序、快速排序、希尔排序
pythoncjavac++
博客等级 码龄5年 718粉丝 71原创
评论 9
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

pythoncjavac++

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值