数据结构-二叉树-堆

news2024/11/17 16:25:09

一、物理结构和逻辑结构

在内存中的存储结构,逻辑结构为想象出来的存储结构。

二、完全二叉树的顺序存储结构

parent = (child - 1)/2

leftchild = 2*parent + 1;

rightchild = 2*parent +2

上面的顺序结构只适合存储完全二叉树。如果存储,会浪费很多的空间。

三、堆

1、堆的分类

小根堆:树中所有的父亲都小于或等于孩子。

大根堆:树中所有的父亲都大于或等于孩子。

接下来我们需要定义一个堆。定义过程如下:

创建堆的时候会涉及到一个向上调整的算法:我们可以画图表示这一过程

void UpAdjust(HPDataType* a, int child)
{
	assert(a);
	int parent = (child - 1) / 2;
	//建立大堆
	while (child > 0)
	{
		if (a[child] > a[parent])
		{
			//交换两个数字
			Swap(&a[child], &a[parent]);
			child = parent;
			parent = (child - 1) / 2;
		}
		else
		{
			break;
		}
	}
}

删除堆顶数据需要涉及到向下调整

这里不能挪动数据。原因有两个,效率低下,父子兄弟关系全乱了。

思路就是:把头部数据和尾部数据交换。删除尾部数据,然后进行向下调整

这样删除的优点是 效率高,保持了大部分堆的父子关系。

向下调整的过程中我们需要和儿子中最大的进行比较。这样才能保证堆的关系不变。

没有孩子时结束,转换一下就是child < size。

void DownAdjust(HPDataType* a,int parent,int size)
{
	int child = 2 * parent + 1;

	while (child < size)
	{	
		//选出最大的那一个孩子
		if (child + 1 < size && a[child] < a[child + 1])
		{
			child++;
		}

		if (a[child] > a[parent])
		{
			//交换两个数字
			Swap(&a[child], &a[parent]);
			parent = child;
			child = 2 * parent + 1;
		}
		else
		{
			break;
		}
	}
}

整体实现

#include "heap.h"

void HeapInit(HP* hp)
{
	assert(hp);
	hp->a = (HPDataType*)malloc(sizeof(HPDataType) * SIZE);
	hp->size = 0;
	hp->capacity = SIZE;
}

void AddCapacity(HP* hp)
{
	assert(hp);
	if (hp->size == hp->capacity)
	{
		HPDataType* temp = (HPDataType*)realloc(hp->a, sizeof(HPDataType) * hp->capacity * 2);
		if (temp == NULL)
		{
			perror("realloc failed");
			return;
		}
		hp->a = temp;
		hp->capacity *= 2;
	}
}
void Swap(int* left, int* right)
{
	int temp = *left;
	*left = *right;
	*right = temp;
}
//除了child的位置,前面的数据构成堆
void UpAdjust(HPDataType* a, int child)
{
	int parent = (child - 1) / 2;
	//建立大堆
	while (child > 0)
	{
		if (a[child] > a[parent])
		{
			//交换两个数字
			Swap(&a[child], &a[parent]);
			child = parent;
			parent = (child - 1) / 2;
		}
		else
		{
			break;
		}
	}
}

void HeapPush(HP* hp, HPDataType x)
{
	//考虑扩容的问题
	AddCapacity(hp);
	//插入数据
	hp->a[hp->size++] = x;
	//还需要考虑向上调整的问题。
	UpAdjust(hp->a, hp->size - 1);
}

void DownAdjust(HPDataType* a,int parent,int size)
{
	int child = 2 * parent + 1;

	while (child < size)
	{	
		//选出最大的那一个孩子
		if (child + 1 < size && a[child] < a[child + 1])
		{
			child++;
		}

		if (a[child] > a[parent])
		{
			//交换两个数字
			Swap(&a[child], &a[parent]);
			parent = child;
			child = 2 * parent + 1;
		}
		else
		{
			break;
		}
	}
}
//删除头部的数据
void HeapPop(HP* hp)
{
	assert(hp);
	assert(!HeapEmpty(hp));
	//首先交换头和尾的数字
	Swap(&hp->a[0], &hp->a[hp->size-1]);
	//然后删除尾的数字
	hp->size--;
	//向下调整恢复堆的原型 向下调整的左右子树一定是堆
	DownAdjust(hp->a, 0, hp->size);
}

HPDataType HeapTop(HP* hp)
{
	assert(hp);
	return hp->a[0];
}
bool HeapEmpty(HP* hp)
{
	assert(hp);
	return hp->size == 0;
}
int HeapSize(HP* hp)
{
	assert(hp);
	return hp->size;
}

四、堆排

对数组进行排序。我们可以把它直接搞成一个堆,建堆操作

1、向上调整建堆

(1)把第一个数看成一个堆中的数。后来的数进行向上调整建立堆。 O(nlogn)

(2)排升序需要建大堆,减小堆关系就都乱了

利用向上调整建大堆时我们可以交换堆头和堆尾的值。然后在进行向下调整选出次小的值,如此往复。

堆排的过程如下

堆排代码:

void HeapSort(int* a,int n)
{
	//首先建立大堆
	for (int i = 1; i < n; i++)
	{
		UpAdjust(a, i);
	}

	//交换堆头和堆尾的数字选出最大的数字放到堆尾
	//然后向下调整
	int end = n - 1;
	while (end > 0)
	{
		Swap(&a[end], &a[0]);
		DownAdjust(a, 0, end);
		end--;
	}
}

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

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

相关文章

Hadoop 启动!

​2024/4/22 上个星期我们已经完成了Hadoop的安装及配置文件的修改 下面 我们将namenode进行一下初始化 hdfs namenode -format (创建文件存储目录&#xff1a;账本目录namenode datanode的目录) 我们在配置时 这就是用来设置账本目录的 我们做完格式化后 tmp目录就出现了 …

权威认证!瀚高股份IvorySQL通过强制性国标GB18030-2022最高级别认证

近日&#xff0c;GB 18030-2022《信息技术 中文编码字符集》应用推广大会暨“汉字守护计划”成果发布会在京召开。瀚高股份开源关系型数据库IvorySQL通过 GB 18030-2022《信息技术 中文编码字符集》强制性国家标准测试&#xff0c;达到最高实现级别&#xff08;3级&#xff09;…

管理之窗:调动下属积极性,难道就是涨工资么?

很多领导在日常管理中&#xff0c;总遇到下属积极性不强的局面&#xff0c;但是很多人总以为涨工资就能解决问题&#xff0c;其实不然&#xff0c;很多下属积极性的强弱和上级的领导力和调动积极性的政策密切相关。 前几天一个企业家来聊&#xff0c;提到了他们单位的人力资源部…

NXP应用随记(七):S32K3XX复位与启动阅读记录

目录 1、复位过程 1.1、概述 1.2、复位产生模块 1.2.1、上电复位 1.2.2、破坏性复位 1.2.3、功能复位 1.3、芯片复位及引导概述 1.4、重置和启动流程图 1.5、复位块序列 2、上电复位 3、破坏性复位 4、功能复位 5、设备配置格式(DCF) 6、重置专题 6.1、重置引脚行…

趋势分析是什么?市场趋势分析的经典方法,从数据中识别机会

趋势分析是把不同时期数据中的相同指标或比率进行比较&#xff0c;观察其增减变动情况及变动幅度&#xff0c;考查发展趋势&#xff0c;预测发展前景的一种方法。 基本原理是在一定时间范围内&#xff0c;通过观察数据的趋势性&#xff0c;发现数据背后的规律性变化。 趋势分析…

应用在智能手环测温功能中的数字温度传感芯片

智能手环是一种穿戴式智能设备。通过智能手环&#xff0c;用户可以记录日常生活中的锻炼、睡眠、部分还有饮食等实时数据&#xff0c;并将这些数据与手机、平等同步。智能手环是一种穿戴式智能设备。通过这款手环&#xff0c;用户可以记录日常生活中的锻炼、睡眠和饮食等实时数…

上位机图像处理和嵌入式模块部署(树莓派4b与mcu固件升级)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 在一个系统当中&#xff0c;可能不止需要树莓派4b一个设备&#xff0c;有的时候还需要搭载一个mcu&#xff0c;做一些运动控制的事情。比如说&…

react —— useState 深入

基础用法 useState Hook 提供了这两个功能&#xff1a; State 变量 在第一次重新渲染期间&#xff0c;这将具有作为参数传递的值State setter 函数 set 函数将允许将状态的值更新为不同的值&#xff0c;如果 set 函数中提供的值不同&#xff0c;则将触发重新渲染。 注意&…

【stomp 实战】spring websocket源码分析之握手请求的处理

上一节【搭建一套websocket推送平台】我们通过一个项目&#xff0c;实现了一套推送平台。由于spring框架对于websocket的支持和stomp协议的良好封装&#xff0c;我们很容易地就实现了websocket的消息推送功能。虽然搭建这么一套推送系统不难&#xff0c;但是如果不了解其底层原…

2024年Q1企业邮箱安全性研究报告:钓鱼邮件同比增长59.9%

4月23日&#xff0c;Coremail邮件安全联合北京中睿天下信息技术有限公司发布《2024年第一季度企业邮箱安全性研究报告》。对当前企业邮箱的应用状况和安全风险进行了分析。 1、垃圾邮件持续增长 根据Coremail邮件安全人工智能实验室最新数据显示&#xff0c;2024年第一季度&am…

【Web】第三次

【Web】第三次 1.完成学校官方网站页面制作2.使用动画完成过渡变换效果 1.完成学校官方网站页面制作 2.使用动画完成过渡变换效果 1.完成学校官方网站页面制作 html&#xff1a; <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://…

【从后端日志文件中过滤出sql语句】

从后端日志文件中过滤出sql语句 why?思路日志文件的格式 结果 why? 为什么会有这种需求&#xff1f;&#xff0c;mysql数据不小心被删了完全可以从备份数据恢复&#xff0c;或者从binlog中恢复&#xff0c;但是如果前面这两种方法没办法处理&#xff08;没有备份数据库文件、…

opencv基础篇 ——(八)图像平滑滤波

均值滤波blur 用于对图像进行均值滤波&#xff08;Mean Filtering&#xff09;的函数。它通过对图像中每个像素点邻域内所有像素值求平均来计算新的像素值&#xff0c;以此达到平滑图像、降低噪声和消除细节的目的 函数原型&#xff1a; void cv::blur(InputArray src,Output…

百面算法工程师 | 分类和聚类

目录 6.1 为什么正确率有时不能有效评估分类算法&#xff1f; 6.2 什么样的分类器最好&#xff1f; 6.3 什么是聚类&#xff0c;你知道哪些聚类算法&#xff1f; 6.4 K-Means聚类算法如何调优? 6.5 K-Means聚类算法如何选择初始点? 6.6 K-Means聚类聚的是特征还是样本 …

贪吃蛇身子改进加贪吃蛇向右移动

1. 蛇移动的思想&#xff1a; 其实就是删除头节点 &#xff0c;增加尾节点&#xff1b;一句代码搞定 struct Snake *p; p head; head head -> next; free(p) 防止造成多的空间节点 2.增加尾节点代码思想&#xff1a; 2.1 .开辟new 节点的空间 struct Snake *new (stru…

2015年中国电子地图数据

这是一份收藏得比较久的电子地图数据&#xff0c;虽然很比较旧&#xff0c;但数据内容很丰富&#xff0c;它可以在一些GIS系统中作测试用。 2015中国电子地图 2015年中国电子地图数据的压缩包有3.29GB大小&#xff0c;如下图所示。 压缩文件大小 该数据进行解压之后&…

CentOS 7虚拟机配置过程中所需组件的安装(二)

1.安装net-tools组件&#xff08;解决无 ifconfig&#xff09; # yum install net-tools 2.安装gcc、c编译器以及内核文件 # yum -y install gcc gcc-c kernel-devel 验证安装成功 3.安装nano&#xff08;文本编辑器&#xff09; # yum install nano

Qt 把.exe打包成安装文件形式

目录 1.下载工具 Qt Installer Framework2.将bin文件添加到环境变量3.拷贝startmenu示例-备用4.准备Qt Release打包好的程序5.把Release打包好的程序放到packages\org.qtproject.ifw.example\data文件夹下6.生成安装包7.修改安装包图标8.修改主程序程序安装引导-创建快捷键9.添…

vue快速入门(四十四)自定义组件

注释很详细&#xff0c;直接上代码 上一篇 新增内容 全局注册自定义组件并应用局部注册自定义组件并应用 此篇使用了axios模块没有安装导入的先看这一篇 axios模块下载与导入 源码 main.js import Vue from vue import App from ./App.vue//全局引入axios // 引入axios impor…

(九)Pandas表格样式 学习简要笔记 #Python #CDA学习打卡

目录 一. Pandas表格样式 1&#xff09;举例数据 2&#xff09;字体颜色 3&#xff09;背景高亮 4&#xff09;极值背景高亮 &#xff08;a&#xff09;高亮最大值 highlight_max() &#xff08;b&#xff09;高亮最小值 highlight_min() &#xff08;c&#xff09;同时…