数据结构:二叉树、堆
目录
一.树的概念
二、二叉树
1.二叉树的概念
2.特殊类型的二叉树
3.二叉树的性质
4.二叉树存储的结构
三、堆
1.堆的概念
2.堆的实现
Heap.h
Heap.c

一.树的概念

注意,树的同一层中不能有关联,否侧就不是树了,就变成图了,例如:

由于B和C存在关联,这就不是树了。
有关树的一些重要概念:

二、二叉树
1.二叉树的概念
二叉树由一个根节点加上两棵别称为左子树和右子树的二叉树组成
它具有两个特点:不存在度大于2的节点;子树有左右之分,次序不能颠倒,故二叉树是有序树

各类型二叉树集合:

2.特殊类型的二叉树
满二叉树:所有非叶子节点都有两个子节点,且所有叶子节点都在同一层
完全二叉树:除了最后一层,每一层都是满的,且最后一层的叶子节点都尽可能靠左排列
二叉排序树:左子树所有节点的值小于根节点的值,右子树所有节点的值大于根节点的值,且左右子树也分别是二叉排序树

3.二叉树的性质
(1) 对于具有n个节点的完全二叉树,如果按照从上到下从左到右的顺序对所有节点从0开始编号,则序号为i的节点有:其双亲节点序号为(i-1)/2;其左孩子节点序号为i*2+1,右孩子节点序号为i*2+2,注意i*2+1和i*2+2要小于n,合法性
(2)规定根节点层数为1,具有n个节点的满二叉树深度为h=log2(n+1)
(3)规定根节点层数为1,第i层最大节点数为2^(i-1)
(4)规定根节点层数为1,深度为h的二叉树的最大节点数为2^h-1
4.二叉树存储的结构
分为顺序存储结构和链式存储结构,其中用顺序存储结构来实现完全二叉树就是接下来重点介绍的堆。
链式存储:用链表来表示一棵二叉树,即用链来指示元素的逻辑关系。 通常的方法是链表中每个结点由三个域组成,数据域和左右指针域,左右指针分别用来给出该结点左孩子和右孩子所在的链结点的存储地址 。
顺序存储:顺序结构存储就是使用数组来存储,一般使用数组只适合表示完全二叉树,因为不是完全二叉树会有空间的浪费。而现实中使用中只有堆才会使用数组来存储。二叉树顺序存储在物理上是一个数组,在逻辑上是一颗二叉树。
三、堆
1.堆的概念
堆可以看作一种特殊类型的完全二叉树,分为大堆和小堆,根节点最大的称为大堆,根节点最小的称为小堆。
大堆:谁大谁当爹,但兄弟间无绝对大小关系
小堆:谁小谁当爹,但兄第间无绝对大小关系
2.堆的实现
升序:建大堆
降序:建小堆
Heap.h
#include<stdlib.h>
#include<assert.h>
#include<stdio.h>
#include<stdbool.h>typedef int HDataType;
typedef struct Heap
{HDataType* arr;int size;int capacity;
}Heap;//堆的初始化
void HeapInit(Heap* obj);
// 堆的插入
void HeapPush(Heap* obj, HDataType x);
// 堆的删除
void HeapPop(Heap* obj);
// 取堆顶的数据
HDataType HeapTop(Heap* obj);
// 堆的数据个数
int HeapSize(Heap* obj);
// 堆的判空
bool HeapEmpty(Heap* obj);
// 堆的销毁
void HeapDestroy(Heap* obj); Heap.c
#include"Heap.h"void HeapInit(Heap* php)
{php->capacity = php->size = 0;php->arr = NULL;
}//扩容
void Exp(Heap* obj)
{if (obj->size == obj->capacity){int new_capeccity = obj->capacity == 0 ? 4 : obj->capacity * 2;HDataType* tem = (HDataType*)realloc(obj->arr, sizeof(HDataType) * new_capeccity);if (tem == NULL){assert("realloc");}obj->arr = tem;obj->capacity = new_capeccity;}
}//交换
void Swap(HDataType* child, HDataType* parent)
{HDataType tem = *child;*child = *parent;*parent = tem;
}//向上调整
//这里假设是小堆进行调整
//如果是大堆,将if处改为大于号即可
void UpAdjust(HDataType* p,int child)
{//通过计算找父母HDataType parent = (child - 1) / 2;while (child > 0){if (p[child] < p[parent]){//交换Swap(&p[child], &p[parent]);//交换后,将parent的位置给给child,继续计算下一个parentchild = parent;//把父母给孩子parent = (child - 1) / 2;//得到新的父母}else{break;}}
}//插入
//先向堆尾插入元素,再根据大堆还是小堆向上调整
void HeapPush(Heap* obj,HDataType x)
{assert(obj);Exp(obj);obj->arr[obj->size] = x;obj->size++;//这个时候我们需要向上UpAdjust(obj->arr, obj->size - 1);
}//向下调整
//这里假设是小堆
//如果是大堆,将两个if处改为大于号即可
void DownAdjust(HDataType* p,int n,int parent)
{//计算出左孩子int child = parent * 2 + 1;while (child < n){if (child + 1 < n && p[child + 1] < p[child]) {//如果右儿子小于左儿子,直接++到右儿子的位置++child;//child+1<n是为了避免越界访问,因为每次算出的是左孩子,堆尾不一定是右孩子}if (p[child] < p[parent])//如果child<parent,就交换,要把小的往上走{//这边操作一样,算法不同Swap(&p[child], &p[parent]);parent = child;//把孩子给父母child = parent * 2 + 1;//得到新的孩子}else{break;}}
}//删除堆顶元素
//这里是小堆,删的实际是最小元素
void HeapPop(Heap* obj)
{assert(obj);assert(obj->arr);assert(obj->size > 0);//堆内无元素则不存在删的问题//1.先交换堆顶和堆尾的元素,避免中间节点之间关系全部混乱Swap(&obj->arr[0], &obj->arr[obj->size - 1]);//2.删obj->size--;//3.这里我们假设的是小堆,而当前交换后显然不是小堆,故向下调整,将堆中次小元素调到堆顶DownAdjust(obj->arr, obj->size, 0);
}//获取堆顶元素
HDataType HeapTop(Heap* obj)
{assert(obj);return obj->arr[0];
}//获取堆中数据的个数
int HeapSize(Heap* obj)
{assert(obj);return obj->size;
}//判空
bool HeapEmpty(Heap* obj)
{assert(obj);return obj->size == 0;
}//堆的销毁
void HeapDestroy(Heap* obj)
{assert(obj);assert(obj->arr);free(obj->arr);obj->arr = NULL;obj->capacity = obj->size = 0;
} test.c

cl:以上代码和顺序表的实现是很相似的,最大区别是堆独有的特点,也就是建堆,堆尾插入元素时进行向上调整,堆顶删除元素时进行向下调整,这两步是最关键的算法,是保证堆的特点(大小堆)的关键。
相关文章:
数据结构:二叉树、堆
目录 一.树的概念 二、二叉树 1.二叉树的概念 2.特殊类型的二叉树 3.二叉树的性质 4.二叉树存储的结构 三、堆 1.堆的概念 2.堆的实现 Heap.h Heap.c 一.树的概念 注意,树的同一层中不能有关联,否侧就不是树了,就变成图了ÿ…...
hi3798mv100 linux 移植
# Linux开发环境搭建 ## uboot编译 1. 必须先安装gcc,要不然make 等命令无法使用 2. 配置arm 交叉编译链 # gcc sudo apt-get install gcc-9 gcc -v# 安装 Linaro gcc-arm-linux-gnueabihf,注意不是arm-linux-gnueabihf-gcc sudo apt-get install ar…...
Docker-Harbor概述及构建
文章目录 一、Docker Harbor概述1.Harbor的特性2.Harbor的构成 二、搭建本地私有仓库三、部署 Docker-Harbor 服务四、在其他客户端上传镜像五、维护管理Harbor 一、Docker Harbor概述 Harbor 是 VMware 公司开源的企业级 Docker Registry 项目,其目标是帮助用户迅…...
部署项目最新教程
3.3安装mysql 运行代码: yum install mysql 运行代码: yum install mysql-server 中间还是一样要输入y然后回车 运行代码: yum install mysql-devel 好,经过上面三步,mysql安装成功,现在启动mysql…...
linux证明变量扩展在路径名扩展之前执行
题目:怎么设计一组命令来证明变量扩展在路径名扩展之前执行。 为了证明变量扩展在路径名扩展之前执行,可以通过编写一个简单的 shell 脚本来观察这两个过程的顺序。我们可以使用以下步骤进行设计: 步骤 1:准备环境 在你选择的 …...
CentOS 7.9安装MySQL
下载Linux版MySQL安装包 下载地址https://downloads.mysql.com/archives/community/ 下载解压后 安装,按照从上至下顺序,一条一条执行即可安装完毕。 进入到rpm所在目录rpm -ivh mysql-community-common-8.0.26-1.el7.x86_64.rpm rpm -ivh mysql-comm…...
MacOS虚拟机安装Windows停滞在“让我们为你连接到网络”,如何解决?
1. 问题描述 MacOS在虚拟机安装win11过程中,停止在“让我们为你连接到网络”步骤,页面没有任何可以点击的按钮,进行下一步操作。 2. 解决方案(亲测有效) 到达该界面,按下ShiftF10(Windows&…...
黑马程序员Java笔记整理(day03)
1.switch 2.for与while对比 3.嵌套定义,输出的区别性 4.break与continue 5.随机数生成的两种方式 6.Random 7.随机验证码...
centos7更换阿里云镜像源操作步骤及命令
centos7更换阿里云镜像源 在CentOS 7上更换为阿里云的镜像源可以通过以下步骤进行: 备份当前的YUM源配置文件 sudo cp -a /etc/yum.repos.d /etc/yum.repos.d.backup清理原有的YUM源配置文件 sudo rm -f /etc/yum.repos.d/*.repo下载阿里云的CentOS 7源配置文件 …...
冲刺大厂 | 一个线程调用两次start()方法会出现什么现象?
大家好,我是冰河~~ 今天给大家分享的面试题是:一个线程调用两次start()方法会出现什么现象?这道面试题是一道关于多线程的基础面试题,很多小伙伴对这个面试题不太了解,其实,如果你看过JDK中关于Thread类的…...
leaflet(一)初始化地图
Leaflet 与天地图结合使用,可以通过天地图提供的 API 获取地图瓦片,并在 Leaflet 地图上显示。 1. 安装依赖 首先,确保你已经安装了 Leaflet 和 Vue: npm install leaflet npm install vue-leaflet npm install leaflet.tilela…...
Unity开发Hololens项目
Unity打包Hololens设备 目录Visual Studio2019 / Visual Studio2022 远端部署设置Visual Studio2019 / Visual Studio2022 USB部署设置Hololens设备如何查找自身IPHololens设备门户Unity工程内的打包设置 目录 记录下自己做MR相关:Unity和HoloLens设备的历程。 Vi…...
立志最细,FreeRtos的中断管理(Interrupt Management)函数,详解!!!
前言:本文参考,韦东山老师开发文档,连接放在最后。 为什么需要中断管理函数? 在FreeRtos操作系统中,需要实时响应性,也就是随时随地必须保证正常多任务的运行,如果有中断发生,因为中…...
作业2-线性回归的Matlab代码实现
一、前言 相关配置:Matlab 2020a(版本的影响应该不大,.m代码基本都能运行,个人感觉就是Simulink对版本的要求高一些) 二、任务描述 基于近两节课的理论推导,用代码实现线性回归,并对预测结果进…...
用jQuery在canvas上绘制绝对定位的元素
在Web开发中,我们经常需要在canvas上精确定位和绘制元素。虽然canvas本身不支持DOM元素的定位,但我们可以借助jQuery来实现这一功能。本文将介绍如何使用jQuery在canvas上实现元素的绝对定位。 1. 基本思路 我们的基本思路是: 创建一个包含canvas的容器div将需要定位的元素放…...
Android中 tools:text 和 android:text区别
首先引入命名空间 <androidx.constraintlayout.widget.ConstraintLayoutxmlns:android"http://schemas.android.com/apk/res/android"xmlns:tools"http://schemas.android.com/tools"/androidx.constraintlayout.widget.ConstraintLayout> tools:te…...
Wordpress GutenKit 插件 远程文件写入致RCE漏洞复现(CVE-2024-9234)
0x01 产品简介 GutenKit 是一个WordPress的页面构建器,在 Gutenberg 设计您的下一个 WordPress 网站。借助 Gutenberg 的原生拖放界面、50+ WordPress 块、14+ 多功能模块和 500+ 模板,您可以在几分钟内创建专业、响应迅速的 Web 内容。 0x02 漏洞概述 Wordpress GutenKit…...
Redis历史漏洞未授权RCE复现
Redis是一个开源的内存数据库,它用于存储数据,并提供高性能、可扩展性和丰富的数据结构支持。 Redis复现文章 Redisssrf漏洞利用探测内网 RedisInsight/RedisDesktopManager可视化连接工具 漏洞原理 (1)redis绑定在 0.0.0.0:…...
Greenhills学习总结
学习背景:近期参与xx项目过程中,遇到较多的关于代码集成编译的知识盲区,因此需要进行相关知识的学习和扫盲。 参考资料:GreenHills2017.7编译手册:本手册是GreenHills 2017.7.14版编译器的软件使用手册。该手册详细介绍了GreenHi…...
【深入学习Redis丨第八篇】详解Redis数据持久化机制
前言 Redis支持两种数据持久化方式:RDB方式和AOF方式。前者会根据配置的规则定时将内存中的数据持久化到硬盘上,后者则是在每次执行写命令之后将命令记录下来。两种持久化方式可以单独使用,但是通常会将两者结合使用。 一、持久化 1.1、什么…...
数据结构之字典树(Trie)
字典树(Trie)详解 1. 引言 字典树(Trie),也称为前缀树或单词查找树,是一种特殊的树形数据结构,用于高效地存储和检索字符串集合。它特别适用于需要快速查找前缀匹配的场景,如自动补全…...
商用车辆电池健康数据深度解析:从真实充电记录到寿命预测
商用车辆电池健康数据深度解析:从真实充电记录到寿命预测 【免费下载链接】battery-charging-data-of-on-road-electric-vehicles This repository is transfered from the personal account of Dr. Zhognwei Deng (Michael Teng) 项目地址: https://gitcode.com/…...
ESP32开发板选型指南:从Arduino到NodeMCU,哪款更适合你的项目?
ESP32开发板选型指南:从Arduino到NodeMCU,哪款更适合你的项目? 在物联网和嵌入式开发领域,ESP32系列开发板凭借其出色的性价比和丰富的功能,已经成为众多开发者的首选。面对市场上琳琅满目的ESP32开发板型号࿰…...
从零到精通:Vue3.0中使用vuedraggable实现完美拖拽功能的5个关键技巧
从零到精通:Vue3.0中使用vuedraggable实现完美拖拽功能的5个关键技巧 在当今前端开发领域,交互体验的重要性日益凸显,而拖拽功能作为提升用户操作直观性的核心手段,已经成为现代Web应用的标配。Vue3.0凭借其出色的响应式系统和组合…...
Windows 11系统优化工具:让你的电脑更高效、更私密
Windows 11系统优化工具:让你的电脑更高效、更私密 【免费下载链接】Win11Debloat A simple, lightweight PowerShell script that allows you to remove pre-installed apps, disable telemetry, as well as perform various other changes to declutter and custo…...
YOLOv5模型从Windows迁移到Linux服务器,遇到‘WindowsPath‘错误?别慌,5分钟搞定它
YOLOv5跨平台迁移实战:彻底解决WindowsPath兼容性问题 当我们将训练好的YOLOv5模型从Windows开发环境迁移到Linux生产服务器时,经常会遇到NotImplementedError: cannot instantiate WindowsPath on your system这类路径兼容性错误。这背后反映的是跨平台…...
OpenClaw移动端适配:Qwen3-14b_int4_awq通过Termux在安卓手机运行
OpenClaw移动端适配:Qwen3-14b_int4_awq通过Termux在安卓手机运行 1. 为什么要在手机上部署OpenClaw? 去年夏天的一个深夜,我正躺在沙发上刷手机,突然接到一个紧急需求:需要立即处理一批文件并生成报告。当时手边没有…...
douyin-downloader:高效采集抖音内容的全流程解决方案
douyin-downloader:高效采集抖音内容的全流程解决方案 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback suppo…...
什么是技术性SEO,如何进行优化_如何优化网站的页面标题(title)
什么是技术性SEO 在数字营销领域,SEO(搜索引擎优化)是提高网站在搜索引擎结果页面(SERP)中排名的关键技术。SEO主要分为技术性SEO和内容性SEO两大类。技术性SEO是指通过优化网站的技术结构和性能,提升搜索…...
亲测有效!5个无广告免费源码网 —— 会员源码网深度解析
在当今数字化时代,源码资源对于开发者、创业者和企业来说至关重要。一个优质的源码网站不仅能提供丰富的代码资源,还能促进技术交流和创新。今天,我要向大家推荐一个亲测有效的无广告免费源码网——会员源码网。会员源码网简介会员源码网是一…...
