当前位置: 首页 > news >正文

数据结构:二叉树、堆

目录

一.树的概念

二、二叉树

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 一.树的概念 注意&#xff0c;树的同一层中不能有关联&#xff0c;否侧就不是树了&#xff0c;就变成图了&#xff…...

hi3798mv100 linux 移植

# Linux开发环境搭建 ## uboot编译 1. 必须先安装gcc&#xff0c;要不然make 等命令无法使用 2. 配置arm 交叉编译链 # gcc sudo apt-get install gcc-9 gcc -v# 安装 Linaro gcc-arm-linux-gnueabihf&#xff0c;注意不是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 项目&#xff0c;其目标是帮助用户迅…...

部署项目最新教程

​ 3.3安装mysql 运行代码&#xff1a; yum install mysql 运行代码&#xff1a; yum install mysql-server 中间还是一样要输入y然后回车 运行代码&#xff1a; yum install mysql-devel 好&#xff0c;经过上面三步&#xff0c;mysql安装成功&#xff0c;现在启动mysql…...

linux证明变量扩展在路径名扩展之前执行

题目&#xff1a;怎么设计一组命令来证明变量扩展在路径名扩展之前执行。 为了证明变量扩展在路径名扩展之前执行&#xff0c;可以通过编写一个简单的 shell 脚本来观察这两个过程的顺序。我们可以使用以下步骤进行设计&#xff1a; 步骤 1&#xff1a;准备环境 在你选择的 …...

CentOS 7.9安装MySQL

下载Linux版MySQL安装包 下载地址https://downloads.mysql.com/archives/community/ 下载解压后 安装&#xff0c;按照从上至下顺序&#xff0c;一条一条执行即可安装完毕。 进入到rpm所在目录rpm -ivh mysql-community-common-8.0.26-1.el7.x86_64.rpm rpm -ivh mysql-comm…...

MacOS虚拟机安装Windows停滞在“让我们为你连接到网络”,如何解决?

1. 问题描述 MacOS在虚拟机安装win11过程中&#xff0c;停止在“让我们为你连接到网络”步骤&#xff0c;页面没有任何可以点击的按钮&#xff0c;进行下一步操作。 2. 解决方案&#xff08;亲测有效&#xff09; 到达该界面&#xff0c;按下ShiftF10&#xff08;Windows&…...

黑马程序员Java笔记整理(day03)

1.switch 2.for与while对比 3.嵌套定义,输出的区别性 4.break与continue 5.随机数生成的两种方式 6.Random 7.随机验证码...

centos7更换阿里云镜像源操作步骤及命令

centos7更换阿里云镜像源 在CentOS 7上更换为阿里云的镜像源可以通过以下步骤进行&#xff1a; 备份当前的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()方法会出现什么现象?

大家好&#xff0c;我是冰河~~ 今天给大家分享的面试题是&#xff1a;一个线程调用两次start()方法会出现什么现象&#xff1f;这道面试题是一道关于多线程的基础面试题&#xff0c;很多小伙伴对这个面试题不太了解&#xff0c;其实&#xff0c;如果你看过JDK中关于Thread类的…...

leaflet(一)初始化地图

Leaflet 与天地图结合使用&#xff0c;可以通过天地图提供的 API 获取地图瓦片&#xff0c;并在 Leaflet 地图上显示。 1. 安装依赖 首先&#xff0c;确保你已经安装了 Leaflet 和 Vue&#xff1a; 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相关&#xff1a;Unity和HoloLens设备的历程。 Vi…...

立志最细,FreeRtos的中断管理(Interrupt Management)函数,详解!!!

前言&#xff1a;本文参考&#xff0c;韦东山老师开发文档&#xff0c;连接放在最后。 为什么需要中断管理函数&#xff1f; 在FreeRtos操作系统中&#xff0c;需要实时响应性&#xff0c;也就是随时随地必须保证正常多任务的运行&#xff0c;如果有中断发生&#xff0c;因为中…...

作业2-线性回归的Matlab代码实现

一、前言 相关配置&#xff1a;Matlab 2020a&#xff08;版本的影响应该不大&#xff0c;.m代码基本都能运行&#xff0c;个人感觉就是Simulink对版本的要求高一些&#xff09; 二、任务描述 基于近两节课的理论推导&#xff0c;用代码实现线性回归&#xff0c;并对预测结果进…...

用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是一个开源的内存数据库&#xff0c;它用于存储数据&#xff0c;并提供高性能、可扩展性和丰富的数据结构支持。 Redis复现文章 Redisssrf漏洞利用探测内网 RedisInsight/RedisDesktopManager可视化连接工具 漏洞原理 &#xff08;1&#xff09;redis绑定在 0.0.0.0:…...

Greenhills学习总结

学习背景&#xff1a;近期参与xx项目过程中&#xff0c;遇到较多的关于代码集成编译的知识盲区&#xff0c;因此需要进行相关知识的学习和扫盲。 参考资料&#xff1a;GreenHills2017.7编译手册:本手册是GreenHills 2017.7.14版编译器的软件使用手册。该手册详细介绍了GreenHi…...

【深入学习Redis丨第八篇】详解Redis数据持久化机制

前言 Redis支持两种数据持久化方式&#xff1a;RDB方式和AOF方式。前者会根据配置的规则定时将内存中的数据持久化到硬盘上&#xff0c;后者则是在每次执行写命令之后将命令记录下来。两种持久化方式可以单独使用&#xff0c;但是通常会将两者结合使用。 一、持久化 1.1、什么…...

k8s从入门到放弃之Ingress七层负载

k8s从入门到放弃之Ingress七层负载 在Kubernetes&#xff08;简称K8s&#xff09;中&#xff0c;Ingress是一个API对象&#xff0c;它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress&#xff0c;你可…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练

前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1)&#xff1a;从基础到实战的深度解析-CSDN博客&#xff0c;但实际面试中&#xff0c;企业更关注候选人对复杂场景的应对能力&#xff08;如多设备并发扫描、低功耗与高发现率的平衡&#xff09;和前沿技术的…...

C++.OpenGL (10/64)基础光照(Basic Lighting)

基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...

2023赣州旅游投资集团

单选题 1.“不登高山&#xff0c;不知天之高也&#xff1b;不临深溪&#xff0c;不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...

HarmonyOS运动开发:如何用mpchart绘制运动配速图表

##鸿蒙核心技术##运动开发##Sensor Service Kit&#xff08;传感器服务&#xff09;# 前言 在运动类应用中&#xff0c;运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据&#xff0c;如配速、距离、卡路里消耗等&#xff0c;用户可以更清晰…...

智能AI电话机器人系统的识别能力现状与发展水平

一、引言 随着人工智能技术的飞速发展&#xff0c;AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术&#xff0c;在客户服务、营销推广、信息查询等领域发挥着越来越重要…...

在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)

考察一般的三次多项式&#xff0c;以r为参数&#xff1a; p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]&#xff1b; 此多项式的根为&#xff1a; 尽管看起来这个多项式是特殊的&#xff0c;其实一般的三次多项式都是可以通过线性变换化为这个形式…...

GO协程(Goroutine)问题总结

在使用Go语言来编写代码时&#xff0c;遇到的一些问题总结一下 [参考文档]&#xff1a;https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函数默认的Goroutine 场景再现&#xff1a; 今天在看到这个教程的时候&#xff0c;在自己的电…...

【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看

文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...