C++数据结构:二叉树之一(数组存储)

文章目录

  • 前言
  • 一、二叉树的基本定义
  • 二、二叉树的基本性质
  • 三、二叉树的存储(数组)
  • 总结
    • 原创文章,未经许可,禁止转载


前言

树是一种非线性数据结构,它由若干个节点和边组成。每个节点都有一个值,而边则表示节点之间的关系。树具有层次结构,其中一个节点被称为根节点,它没有父节点。除根节点外,每个节点都有且仅有一个父节点。树的基本性质包括树的深度、高度、度数等。

森林是由若干棵互不相交的树组成的集合。一棵树可以看作是一个仅包含一棵树的森林。

二叉树是一种特殊的树,它的每个节点最多只有两个子节点,分别称为左子节点和右子节点。二叉树是树的一种特殊形式,它具有树的所有基本性质,同时还有一些独特的性质。下图为一个树的结构示意:
在这里插入图片描述
因为B节点的度为3,所以上图是树结构但不是二叉树结构。二叉树在树型数据结构中是非常重要的一部分,很多实际问题抽象后的结构往往是二叉树形式的。


一、二叉树的基本定义

二叉树结构在数学中可以用一个有限的集合来表示。这里我们可以用图形的方式来展示二叉树的结构,如下图所示:

在这里插入图片描述

上图表示了二叉树的基本性质,它每个节点最多有两个子节点,可以称度为2,没有分支节点的4、5、6、7可以称之为叶子节点。1节点没有上一层节点,我们称之为根节点,它没有父节点。2节点的度为2,它是一个分支节点,它也是4、5节点的父节点。上图的二叉树有三层,所以我们称之高度或深度为3。

如上所述,学习二叉树,我们先要明白一些常用的术语:

  • 树的度:树中所有节点的度的最大值。度是指一个节点拥有的子节点的个数,明显二叉树的度为2。
  • 节点的度:一个节点拥有的子节点的个数,同上二叉树的节点度为2。
  • 树的高度:也称深度,树中所有节点的层次的最大值。根节点所在的层定义为第一层,它的子节点所在的层为第二层,以此类推。因此,一棵只有一个节点(即根节点)的树的高度为1,而一棵空树(没有节点)的高度为0。上图的二叉树高度为3。
  • 分支节点:度大于零的节点。
  • 叶子节点:度为零的节点。
  • 空树:没有任何节点的树。
  • 完全二叉树:除叶子节点外,每一层的结点都达到最大个数。就是除叶子节点层外,每一个节点都有2个分支节点。

这些术语有助于我们理解和分析二叉树的性质和操作。

二、二叉树的基本性质

对于二叉树,有很多已证明的特性,其中又有几项比较重要的特性我们一定要明白(以下均在非空二叉树条件下):

  • 第 x 层最多有 2x-1个节点。推而广之,深度为 k 的二叉树最多有2k - 1 个节点。
  • 具有 n 个节点的完全二叉树的深度 k = n/2 。如上图所示,节点数是n=7,所以深度k为7/2=3。(对于C++的整数类型,这个公式是成立的,对于python这种弱类型语言应该描述成7//2)
  • 对于完全二叉数,我们以 i 表示节点序号,如上图,i 从上至下,从左至右编号。那么这个完全二叉树满足以下性质:
  • 1、如果i > 1,那么它的父节点为 i/2 (整除)。
  • 2、于上一点相反,如果一个节点存在分支节点,那么它的左子节点为 2i,右子节点为2i + 1。
  • 3、上一点继续推导可以得出,如果2i > n 那么这个结点没有分支节点,它是一个叶子节点。
  • 如果 2i + 1 > n 那么这个结点没有右分支节点。
  • 如果2i == n,这个二叉树就不是完全二叉树。

为什么要搞这些数学公式呢?因为根据这些特性,我们可以把二叉树的存储简化到一个数组就完成了。我们可以假设任一二叉树为完全二叉树,不存在的节点,我们以-1表示,当然也可以用0表示,根节点我们定义为 1,如此我们可以根据以上性质,在一个数组中存储二叉树,以节点编号为数组下标即可!

它非常的方便!并且父节点、左右子节点都可以根据公式得到,是双向可访问的。继续以上图的完全二叉树为例,我们来看看如何在一个数组中存储这个二叉树:
在这里插入图片描述

三、二叉树的存储(数组)

如上图所示,稍一计算便明白,它符合我们前面所述的特性。这种存储方式简直太方便了。我们只需在不存在的下标填0,这可以在数组生成时同步完成。其它下标填入相应数据即可,最大的优点就是可以随机存取任一个节点,这是采用链式存储所不能办到的,必须遍历。当然它的缺点也明显,如果不是完全二叉树,特别是一些歪脖子树,这种方式很浪费空间,如果数据规模很大,可能难以在内存中找到这么大块的连续空间。
下面我们用代码实现这个存储方式:

#include <iostream>
using namespace std;

const int MAX_SIZE = 100;   //数组最大容量
int tree[MAX_SIZE];         //存储二叉树的数组
int n;                      //节点个数

//前序遍历
void preOrder(int root){
    if (root > n) return;      //超出范围,返回
    cout << tree[root] << " "; //访问根节点
    preOrder(root * 2);        //访问左子树
    preOrder(root * 2 + 1);    //访问右子树
}

//中序遍历
void inOrder(int root){
    if (root > n) return;        //超出范围,返回
    inOrder(root * 2);          //访问左子树
    cout << tree[root] << " ";   //访问根节点
    inOrder(root * 2 + 1);      //访问右子树
}

以上是用了递归遍历的方法,递归遍历是一种简单直观的方法,它利用了递归函数调用自身的特性来遍历树中的节点。非递归遍历则需要使用栈或队列等数据结构来辅助遍历。

至于没给出的后序遍历只是改一下代码的顺序,层序遍历更是只要从1到n遍历数组即可。那真是相当的方便啊~,不过看起来一点二叉树的感觉都没有,作者你是不是在忽悠人啊?哈哈…面向对象的编程就是这么的抽象,心中有树,它就是树。


总结

首先笔者没有忽悠人,这确实是二叉树的存储办法,而且是挺好的一个方法。当然在实际工作中它较少被使用,这种存储方式在工作中可以用于排序二叉树(也称二叉搜索树、有序二叉树)它可以用来实现高效的查找和排序算法,比如堆排序。此外,数组存储二叉树的方式也可以用于实现堆数据结构,如大顶堆和小顶堆,它们常用于实现优先队列等数据结构。

嗯这字数已经够多了,也写累了,链表都写了两篇才完成,二叉树只会更多,下一篇写二叉树的链式存储方式及实用示例。

原创文章,未经许可,禁止转载

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

day17 - 用形状包围图像

在进行图像轮廓提取时&#xff0c;有的情况下不需要我们提取出精确的轮廓&#xff0c;只要提取出一个接近于轮廓的近似多边形&#xff0c;就可以满足后续的操作。 本期我们来学习如何通过设置参数来找出图像的近似多边形。 完成本期内容&#xff0c;你可以&#xff1a; 了解…

算法基础学习笔记——⑨C++STL使用技巧

✨博主&#xff1a;命运之光 ✨专栏&#xff1a;算法基础学习 目录 ✨CSTL简介 ✨CSTL使用技巧 前言&#xff1a;算法学习笔记记录日常分享&#xff0c;需要的看哈O(∩_∩)O&#xff0c;感谢大家的支持&#xff01; ✨CSTL简介 vector变长数组&#xff0c;倍增的思想//系统为…

STM32单片机(三)第一节:GPIO输出

❤️ 专栏简介&#xff1a;本专栏记录了从零学习单片机的过程&#xff0c;其中包括51单片机和STM32单片机两部分&#xff1b;建议先学习51单片机&#xff0c;其是STM32等高级单片机的基础&#xff1b;这样再学习STM32时才能融会贯通。 ☀️ 专栏适用人群 &#xff1a;适用于想要…

驱动开发:内核读写内存浮点数

如前所述&#xff0c;在前几章内容中笔者简单介绍了内存读写的基本实现方式&#xff0c;这其中包括了CR3切换读写&#xff0c;MDL映射读写&#xff0c;内存拷贝读写&#xff0c;本章将在如前所述的读写函数进一步封装&#xff0c;并以此来实现驱动读写内存浮点数的目的。内存浮…

MyBatis操作数据库表和动态SQL的使用

目录 1.MyBatis开发环境的搭建和测试 2.MyBatis基本操作 2.0 准备工作 2.1 新增操作 2.2 删除、修改、查询操作 2.3 #{param} 和 ${param}的使用和区别 2.4 实体对象属性和数据库字段名称不同时如何映射&#xff1f; 3. MyBatis多表查询 3.0 准备工作 3.1 一对一的表…

ELK企业级日志分析系统

ELK概述 为什么要使用 ELK 日志主要包括系统日志、应用程序日志和安全日志。系统运维和开发人员可以通过日志了解服务器软硬件信息、检查配置过程中的错误及错误发生的原因。经常分析日志可以了解服务器的负荷&#xff0c;性能安全性&#xff0c;从而及时采取措施纠正错误。 往…

切比雪夫不等式,大数定律及极限定理。

一.切比雪夫不等式 1.定理 若随机变量X的期望EX和方差DX存在,则对任意ε > 0,有   P{ |X - EX| > ε } < DX/ε2 或 P{ |X - EX| < ε } > 1 - DX/ε2 2.解析定理 ①该定理对 X 服从什么分布不做要求&#xff0c;仅EX DX存在即可。 ②“| |” 由于X某次…

软件测试炸了,作为从业者,你做好准备了吗?

软件测试行业已经发生很大变化&#xff0c;你跟上变化了吗&#xff1f; 岗位少不可怕&#xff0c;要求越来越高也不可怕&#xff0c;可怕的是&#xff0c;软件测试行业已经发生巨变&#xff0c;而你却原地踏步&#xff01;目前一线大厂更多倾向于招收测试开发&#xff0c;或者…

自学网络安全(黑客),一般人我劝你还是算了吧

一、自学网络安全学习的误区和陷阱 1.不要试图先成为一名程序员&#xff08;以编程为基础的学习&#xff09;再开始学习 我在之前的回答中&#xff0c;我都一再强调不要以编程为基础再开始学习网络安全&#xff0c;一般来说&#xff0c;学习编程不但学习周期长&#xff0c;而且…

torch.distributed.launch多卡多机

torch.distributed.launch命令介绍 我们在训练分布式时候&#xff0c;会使用到 torch.distributed.launch 可以通过命令&#xff0c;来打印该模块提供的可选参数 python -m torch.distributed.launch --help usage: launch.py [-h] [--nnodes NNODES] [--node_rank NODE_RANK]…

诚迈科技携智达诚远出席高通汽车技术与合作峰会

5月25日至26日&#xff0c;诚迈科技及旗下的智能汽车操作系统及中间件产品提供商智达诚远作为高通生态伙伴&#xff0c;亮相首届“高通汽车技术与合作峰会”&#xff0c;通过产品展示和主题演讲呈现了基于高通骁龙数字底盘的最新智能座舱技术成果&#xff0c;共同展望智能网联汽…

GcExcel v6.1 支持新的 ‘.sjs‘ 模板文件 ‘.xltx‘ 格式 Crack

GrapeCity Documents for Excel (GcExcel) v6.1 版本现已上线&#xff01;该版本支持新的 SpreadJS .sjs 文件格式和 Excel 模板文件 .xltx 格式。此外&#xff0c;GcExcel 支持更多的SpreadJS兼容性功能和对 GcDataViewer 的多项增强。看看下面的主要亮点。 导入/导出 Spread…

Revit幕墙:用幕墙巧做屋面瓦及如何快速幕墙?

一、Revit中用幕墙巧做屋面瓦 屋面瓦重复性很高&#xff0c;我们如何快速的创建呢?下面我们来学会快速用幕墙来创建屋面瓦的技巧。 1.新建“公制轮廓-竖挺”族&#xff0c;以此来创建瓦的族(以便于载入项目中使用) 2.在轮廓族中绘制瓦的轮廓(轮廓需要闭合)&#xff0c;将族名称…

【JavaSE】Java基础语法(三十四):实现多线程

文章目录 1. 简单了解多线程2. 并发和并行3. 进程和线程4. 实现多线程方式一&#xff1a;继承Thread类【应用】5. 实现多线程方式二&#xff1a;实现Runnable接口【应用】6. 实现多线程方式三: 实现Callable接口【应用】7. 设置和获取线程名称【应用】8. 线程休眠【应用】9. 线…

Z-Library2023现状

网上基本上年年都会传出来Z-Library要被干掉的消息&#xff0c;我一直觉得&#xff0c;如果那真的发生了&#xff0c;会是人类的悲哀。 由于之前我存储的地址又挂了&#xff0c;所以紧急又寻找了一下。 1.朋友帮忙 朋友帮我搜了一下&#xff0c;发现有三个地址。 他说这第一个…

xlsx是什么格式

xlsx是什么格式? xlsx是Excel文档的扩展名&#xff0c;其基于Office Open XML标准的压缩文件格式&#xff0c;取代了其以前专有的默认文件格式&#xff0c;在传统的文件名扩展名后面添加了字母x&#xff0c;即.xlsx取代.xls。 xlsx文件是什么格式? xlsx是Excel表格的文件格…

【P34】JMeter ForEach控制器(ForEach Controller)

文章目录 一、ForEach控制器&#xff08;ForEach Controller&#xff09;参数说明二、准备工作三、测试计划设计 一、ForEach控制器&#xff08;ForEach Controller&#xff09;参数说明 可以对一个组变量进行循环迭代&#xff1b;该组件通常与后置处理器中的 JSON 提取器、正…

桥梁结构健康监测解决方案

城市桥梁担负着城市的交通和运输网络的重要角色&#xff0c;是城市生命线的重要组成部分。然而&#xff0c;随着时间的推移和日益增长的负荷&#xff0c;桥梁可能会受到各种因素的损害&#xff0c;如自然灾害、疲劳、腐蚀等。因此&#xff0c;桥梁结构健康监测变得至关重要&…

chatgpt赋能Python-python中怎么导入numpy

介绍 Python是一种广泛使用的编程语言&#xff0c;具有许多内建功能和模块&#xff0c;让开发者能够快速地编写代码。然而&#xff0c;虽然能够实现许多计算&#xff0c;但是原始Python本身并不足够处理各种科学和数字计算上需要的高效性&#xff0c;因此numpy这个开源的Pytho…

【机器学习】采样方法

文章目录 采样方法11.1 简介11.2 常见采样方法11.2.1 均匀分布采样11.2.2 逆变换采样11.2.3 拒绝采样11.2.4 重要采样11.2.5 Metropolis方法11.2.6 Metropolis-Hasting 算法11.2.7 吉布斯采样 采样方法 11.1 简介 什么是采样 从一个分布中生成一批服从该分布的样本&#xff0c…