【树的概念及其堆的实现】

树的概念及其堆的实现

  • 1.树的概念
  • 2.树的相关概念
  • 3.二叉树的概念
  • 4. 满二叉树和完全二叉树
  • 5.二叉树的存储结构
  • 6.二叉树顺序结构的实现的
  • 7.堆的结构及其实现

1.树的概念

  树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。
有一个特殊的结点,称为根结点,根节点没有前驱结点除根节点外,其余结点被分成M(M>0)个互不相交的集合T1、T2、……、Tm,其中每一个集合Ti(1<= i <= m)又是一棵结构与树类似的子树。每棵子树的根结点有且只有一个前驱,可以有0个或多个后继,因此,树是递归定义的。
注意:树形结构中,子树之间不能有交集,否则就不是树形结构.

Alt

2.树的相关概念

Alt
  *节点的度:一个节点含有子树的个数称为该节点的度。如上图:A的为6

  *叶节点或终端节点:度为0的节点称为叶节点; 如上图:B、C、H、I…等节点为叶节点

  * 非终端节点或分支节点:度不为0的节点; 如上图:D、E、F、G…等节点为分支节点

  *孩子节点或子节点:一个节点含有的子树的根节点称为该节点的子节点; 如上图:B是A的孩子节点

  * 兄弟节点:具有相同父节点的节点互称为兄弟节点; 如上图:B、C是兄弟节点

  * 树的度:一棵树中,最大的节点的度称为树的度; 如上图:树的度为6

  * 节点的层次:从根开始定义起,根为第1层,根的子节点为第2层,以此类推;

  * 树的高度或深度:树中节点的最大层次; 如上图:树的高度为4

  * 堂兄弟节点:双亲在同一层的节点互为堂兄弟;如上图:H、I互为兄弟节点

   * 节点的祖先:从根到该节点所经分支上的所有节点;如上图:A是所有节点的祖先

   * 子孙:以某节点为根的子树中任一节点都称为该节点的子孙。如上图:所有节点都是A的子孙

3.二叉树的概念

 一棵二叉树是结点的一个有限集合,该集合:
 1.或者为空
 2. 由一个根节点加上两棵别称为左子树和右子树的二叉树组成.

Alt
从上图可以看出:
1. 二叉树不存在度大于2的结点
2. 二叉树的子树有左右之分,次序不能颠倒,因此二叉树是有序树.

 注意:对于任意的二叉树都是由以下几种情况复合而成的:
Alt

4. 满二叉树和完全二叉树

 1. 满二叉树:一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。也就是说,如果一个二叉树的层数为K,且结点总数是2^k-1,则它就是满二叉树。
 2.完全二叉树:完全二叉树是效率很高的数据结构,完全二叉树是由满二叉而引出来的。对于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的的结点一一对应时称之为完全二叉树。 要注意的是满二叉树是一种特殊的完全二叉树。

Alt

5.二叉树的存储结构

1. 顺序存储
 顺序结构存储就是使用数组来存储,一般使用数组只适合表示完全二叉树,因为不是完全二叉树会有空间的浪费。而现实中使用中只有堆才会使用数组来存储。二叉树顺序存储在物理上是一个数组,在逻辑上是一颗二叉树。

Alt

2. 链式存储
 二叉树的链式存储结构是指,用链表来表示一棵二叉树,即用链来指示元素的逻辑关系。 通常的方法是链表中每个结点由三个域组成,数据域和左右指针域,左右指针分别用来给出该结点左孩子和右孩子所在的链结点的存储地址 。链式结构又分为二叉链和三叉链,当前我们学习中一般都是二叉链。

Alt

6.二叉树顺序结构的实现的

 普通的二叉树是不适合用数组来存储的,因为可能会存在大量的空间浪费。而完全二叉树更适合使用顺序结构存储。现实中我们通常把堆(一种二叉树)使用顺序结构的数组来存储,需要注意的是这里的堆和操作系统虚拟进程地址空间中的堆是两回事,一个是数据结构,一个是操作系统中管理内存的一块区域分段。

7.堆的结构及其实现

Alt
Alt

 堆是一个完全二叉树,用数据来实现,结构和实现的接口如下:

#define HeapDataType int
typedef struct Heap {
HeapDataType* a;
int size;
int capacity;
}Heap;
void HeapInit(Heap* php);
void HeapDestory(Heap* php);
void HeapPush(Heap* php, HeapDataType x);
HeapDataType HeapTop(Heap* php);
void HeapPop(Heap* php);
bool HeapEmpty(Heap* php);



堆初始化和堆销毁接口如下

void HeapInit(Heap* php)
{assert(php);php->a = NULL;php->capacity = php->size = 0;
}void HeapDestory(Heap* php)
{assert(php);free(php->a);php->a = NULL;php->capacity = php->size = 0;
}

 HeapPush接口的实现,先插入数据,再用向上调整算法,调成堆,以调成小堆为列,介绍向上调整算法。
Alt
  以满二叉树,插入10为例,进行调整,10是孩子,先找到父亲,由于是满二叉树,孩子与父亲的关系为:
 LeftChild = (Parent2)+1;
 RightChild = (Parent
2)+2;
 Parent = (child - 1)/2;

然后,如果孩子比父亲小,则交换,孩子比父亲大,则成立。这儿再说一下循环怎么写,写循环结构就两件事,1.写循环体 2.写循环条件,一定要先写循环体,根据循环体写循环条件,例如上面向上调整算法.
 循环体是什么?
 已经知道最后一个孩子的位置,则通过孩子算出父亲位置,然后孩子与父亲的大小比较,进行交换。若成立,则退出循环。尽管做这样一件事情,那什么时候结束,孩子走到头,父亲没有了,就结束,很自然就找到循环条件。

 具体代码如下:

void Swap(HeapDataType* px, HeapDataType* py)
{HeapDataType tmp = *px;*px = *py;*py = tmp;
}void AdjustUp(HeapDataType* 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(Heap* php, HeapDataType x)
{assert(php);if (php->capacity == php->size){int newcapacity = php->capacity == 0 ? 4 : php->capacity * 2;HeapDataType* tmp = (HeapDataType*)realloc(php->a, sizeof(HeapDataType) * newcapacity);if (tmp == NULL){perror("realloc fail!");return;}php->a = tmp;php->capacity = newcapacity;}php->a[php->size] = x;php->size++;AdjustUp(php->a, php->size - 1);
}

 写接口获得堆顶数据,堆的删除。
 堆的删除,首先堆头和堆位进行交换,然后向下调整,调整成堆。

Alt

 首先,把10和28交换,交换之后,把堆顶元素10删除,把在0位置的28这个元素,向下调整成堆,具体就是找孩子中两个较小的一个跟父亲比较,进行交换,父亲走到头,循环结束,这是孩子已经越界,用孩子来写循环条件。
 代码如下。

void AdjustDown(HeapDataType* a, int parent, int n)
{int child = (parent * 2) + 1;if (a[child] > a[child + 1] && child+1<n){child += 1;}while (child<n){if (a[parent] > a[child]){Swap(&a[parent], &a[child]);parent = child;if (a[child] > a[child + 1] && child + 1 < n){child += 1;}}else{break;}}
}void HeapPop(Heap* php)
{assert(php);assert(php->a);Swap(&php->a[0], &php->a[php->size - 1]);php->size--;AdjustDown(php->a, 0, php->size);
}

 判空很简单

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

 完结!

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

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

相关文章

鸿蒙系统(HarmonyOS)经典红色风格登录页布局

预览 简介 基于鸿蒙系统&#xff08;HarmonyOS&#xff09;开发的现代化登录界面&#xff0c;采用了科技感十足的红色主题设计。该界面结合了流畅的动画效果、精心设计的视觉元素和人性化的交互体验&#xff0c;为用户提供了一个安全、美观且易用的登录入口。 &#x1f3a8; …

C++虚函数多态

class C{ public:void x1(){};void x2(){};};C c; cout << sizeof(c) <<"\n";1字节 class D{ public:void x1(){};void x2(){};virtual void x3(){};//void *vptr看不见的虚函数表指针 }; D d; cout << sizeof(d) <<"\n";8字节类A…

新编辑器编写指南--给自己的备忘

欢迎使用Markdown编辑器 你好&#xff01; 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章&#xff0c;了解一下Markdown的基本语法知识。 新的改变 我们对Markdown编辑器进行了一些功能拓展与语法支持&#x…

目标检测neck算法之MPCA和FSA的源码实现

目标检测neck算法之MPCA和FSA的源码实现 使用BIBM2024 Spatial-Frequency Dual Domain Attention Network For Medical Image Segmentation的Frequency-Spatial Attention和Multi-scale Progressive Channel Attention改进neck. 接下来&#xff0c;我将讲解它的源码操作的实现…

MyBatis-Plus的3.5.7和PageHelper的那个版本对应

MyBatis-Plus的3.5.7和PageHelper的那个版本对应 根据你的知识库中提到的信息&#xff1a; MyBatis-Plus 3.5.7 使用的是 JSqlParser 4.6 版本。PageHelper 若使用了不同版本的 JSqlParser&#xff08;如 4.7&#xff09;&#xff0c;会导致冲突。 ✅ 推荐对应关系 为了保证…

Apifox 6 月产品更新|支持 AI 能力、交互优化、在线文档新增 SEO 设置、gRPC 项目支持前/后置操作

在 2025 年的 API 开发领域&#xff0c;Apifox 作为一款集 API 设计、调试、Mock 和测试于一体的协作平台&#xff0c;已成为开发者的“得力助手”。然而&#xff0c;随着业务需求的不断增长&#xff0c;开发者对工具的效率和功能提出了更高的要求。6 月份&#xff0c;Apifox 推…

Acrobat JavaScript 从浏览器到 PDF 环境的转换

目录 什么是 JavaScript?JavaScript 核心语言与 Acrobat 特定 API学习 JavaScript 核心语言的挑战浏览器与 Acrobat JavaScript 的关键差异在 Acrobat 中运行 JavaScript 代码替代浏览器特定函数的方法后续学习建议什么是 JavaScript? JavaScript 最初于 1995 年作为 Netsca…

OpenCV CUDA模块设备层-----指数运算函数exp()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 OpenCV 的 CUDA 设备端数学函数 中的一个内联函数&#xff0c;用于在 GPU 上对 uchar1 类型&#xff08;单通道图像像素&#xff09;执行指数运算…

C++面向对象5——C++关键字、构造函数与拷贝构造函数

this关键字 C关键字this的深度解析 1. this指针的本质 在C中&#xff0c;this是一个特殊的隐式指针&#xff0c;它存在于每个非静态成员函数内部&#xff0c;指向调用该函数的当前对象。其类型为&#xff1a; 对于非const成员函数&#xff1a;ClassName* const&#xff08;…

人工智能专业:探索未来的智慧前沿

亲戚家的小孩刚高考完&#xff0c;问我人工智能专业是学什么、做什么的。趁机就写一篇吧&#xff01; 人工智能专业&#xff1a;探索未来的智慧前沿 人工智能&#xff08;Artificial Intelligence&#xff0c;简称AI&#xff09;无疑是当今最热门、最具颠覆性的技术之一。它正…

618风控战升级,瑞数信息“动态安全+AI”利剑出鞘

每年的618电商促销季&#xff0c;都是各大电商平台和商家的兵家必争之地。数以亿计的消费者涌入线上平台&#xff0c;期待已久的优惠券、秒杀商品如潮水般涌现&#xff0c;海量交易在瞬间达成&#xff0c;无疑是一场商业狂欢。 然而&#xff0c;在这场狂欢背后&#xff0c;自动…

神经网络的架构

神经网络中的基本术语 以上图为例&#xff0c;相关的术语描述如下&#xff1a; 最左边的称为输⼊层&#xff0c;其中的神经元称为输⼊神经元&#xff1b;最右边的&#xff0c;即输出层包含有输出神经元&#xff1b;本例中的输出神经元只有一个&#xff1b;中间层&#xff0c;既…

安全生产监测预警系统:构筑智能化的安全防线

安全生产监测预警系统是工业安全管理的核心工具&#xff0c;它利用物联网、大数据、人工智能等技术&#xff0c;实现对生产环境、设备运行和人员行为的全方位监测&#xff0c;确保风险早发现、早预警、早处置。其核心功能涵盖实时监测、智能预警、应急处置、数据分析与优化等多…

Java练习题精选6-10

Java练习题精选6-10 一、第六题二、第七题第八题第九题第十题 一、第六题 如何将两个变量的值进行交换&#xff1f;假设变量a1&#xff0c;b2。 public class Main {public static void main(String[] args) {int a 1;int b 2;int tmp;System.out.println("交换前a&qu…

【GESP】C++四级考试大纲知识点梳理, (2) 结构体和二维数组

GESP C四级官方考试大纲中&#xff0c;共有11条考点&#xff0c;本文针对第2条考点进行分析介绍。 &#xff08;2&#xff09;掌握 C结构体、二维及多维数组的基本概念及使用 四级其他考点回顾&#xff1a; 【GESP】C四级考试大纲知识点梳理, (1) 指针 全文详见&#xff1a;【G…

自动化测试--App自动化之项目实战脚本编写及封装流程

1.App测试范围 app自动化测试主要核心测试手机程序 测试方面&#xff1a; 功能测试 安装卸载测试 升级测试 兼容性测试 网络切换&#xff0c;中断测试 横竖屏切换 健壮性 2.测试环境的搭建 需要配置的环境 java jdk Java的环境 Android sdk 安卓环境 python环境…

【Unity】什么是前向渲染、延迟渲染、单通道渲染、多通道渲染?

好的&#xff0c;我们来深入剖析这些核心渲染概念&#xff0c;理解它们的原理、优缺点以及在Unity&#xff08;特别是URP&#xff09;中的应用。 核心概念&#xff1a;渲染路径 (Rendering Path) 渲染路径决定了光照和着色在场景中是如何计算和应用的。它定义了物体被绘制到屏…

OpenCV CUDA模块设备层-----GPU上执行线程安全的 “原子取最大值” 操作函数

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 这是一个 OpenCV 的 CUDA 模块&#xff08;cv::cudev&#xff09; 中封装的原子操作函数&#xff0c;用于在 GPU 上执行线程安全的 “原子取最大…

【nRF52832】【环境搭建 1】【ubuntu下搭建nRF52832开发环境】

本文讲述如何在 ubuntu 22.04 下开发 nRF52832. host 环境说明: $ uname -a Linux leo 6.8.0-60-generic #63~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Tue Apr 22 19:00:15 UTC 2 x86_64 x86_64 x86_64 GNU/Linux1. 安装软件 sudo apt install gcc-arm-none-eabisudo apt-get i…

【Nginx】403 Forbidden错误

当 Nginx 代理配置出现 403 Forbidden 错误时&#xff0c;通常是由于权限或配置问题导致。以下是常见原因和解决方案&#xff1a; 常见原因及解决方法 1. 后端服务器拒绝访问 原因&#xff1a;后端 HTTPS 服务配置了 IP 白名单或访问控制解决&#xff1a; 检查后端服务器&…