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

数据结构:图文详解 树与二叉树(树与二叉树的概念和性质,存储,遍历)


目录

一.树的概念

二.树中重要的概念

三.二叉树的概念

满二叉树

完全二叉树

四.二叉树的性质

五.二叉树的存储

六.二叉树的遍历

前序遍历

中序遍历 

后序遍历 


一.树的概念

树是一种非线性数据结构,它由节点和边组成。树的每个节点可以有零个或多个子节点,其中一个节点被指定为根节点。树的节点之间通过边连接。另外,树形结构中,子树之间不能有交集,否则就不是树形结构。

树的结构具有层级关系,根节点位于最顶层,而叶节点位于最底层。树的形状可以类比于现实生活中的树,根节点相当于树的根部,而分支和叶子节点则相当于树的枝干和叶子。

在计算机科学中,树被广泛用于各种应用,例如文件系统、数据库索引、编译器中的抽象语法树等。树的常见特点是具有唯一的根节点、没有循环的边、可以有任意数量的子节点等。

树的常见操作包括插入新节点、删除节点、查找节点、遍历节点等。常见的树结构包括二叉树、红黑树、AVL树等。树的设计和使用在算法和数据结构领域中非常重要,它可以提供高效的数据存储和检索方式。 


二.树中重要的概念

笔者就以下图作为例子进行说明:

  • 结点的度:一个结点含有子树的个数称为该结点的度; 如上图:A的度为6
  • 树的度:一棵树中,所有结点度的最大值称为树的度; 如上图:树的度为6
  • 叶子结点或终端结点:度为0的结点称为叶结点; 如上图:B、C、H、I...等节点为叶结点
  • 双亲结点或父结点:若一个结点含有子结点,则这个结点称为其子结点的父结点; 如上图:A是B的父结点
  • 孩子结点或子结点:一个结点含有的子树的根结点称为该结点的子结点; 如上图:B是A的孩子结点
  • 根结点:一棵树中,没有双亲结点的结点;如上图:A
  • 结点的层次:从根开始定义起,根为第1层,根的子结点为第2层,以此类推
  • 树的高度或深度:树中结点的最大层次; 如上图:树的高度为4
  • 非终端结点或分支结点:度不为0的结点; 如上图:D、E、F、G...等节点为分支结点
  • 兄弟结点:具有相同父结点的结点互称为兄弟结点; 如上图:B、C是兄弟结点
  • 堂兄弟结点:双亲在同一层的结点互为堂兄弟;如上图:H、I互为兄弟结点
  • 结点的祖先:从根到该结点所经分支上的所有结点;如上图:A是所有结点的祖先
  • 子孙:以某结点为根的子树中任一结点都称为该结点的子孙。如上图:所有结点都是A的子孙
  • 森林:由m(m>=0)棵互不相交的树组成的集合称为森林 

三.二叉树的概念

二叉树是一种常见的树状数据结构,在二叉树中,每个节点最多有两个子节点,分别称为左子节点右子节点。二叉树的特点是每个节点最多只有两个子节点,且子节点的位置是有序的,即左子节点在右子节点之前。

二叉树可以为空,如果一个二叉树不为空,则它一定由根节点左子树右子树组成。每个节点都有一个值,可以是任意类型的数据。

二叉树也可以只有一个节点,如下图所示,根节点不为空,但是左子树和右子树为空,这样的二叉树也是允许存在的

总的来说,对于任意一颗二叉树,它都是由以下几部分复合而成的

二叉树可以用来表示许多实际问题,例如计算机科学中的排序和搜索算法。在二叉树中,有一些特殊的类型,如满二叉树、完全二叉树和平衡二叉树等。二叉树还可以通过遍历算法来访问其中的节点,最常见的遍历算法有前序遍历、中序遍历和后序遍历。

二叉树中还有以下俩个常见的特殊的二叉树

满二叉树

一棵二叉树,如果每层的结点数都达到最大值,则这棵二叉树就是满二叉树。也就是说,如果一棵二叉树的层数为 k ,且结点总数是 2^{k}-1,则它就是满二叉树。

完全二叉树

完全二叉树是由满二叉树而引出来的,对于深度为 k 的,有 n 个结点的二叉树,当且仅当其每一个结点都与深度为 k 的满二叉树中编号从0n-1的结点一一对应时称之为完全二叉树。 要注意的是满二叉树是一种特殊的完全二叉树


四.二叉树的性质

  1. 若规定根结点的层数为1,则一棵非空二叉树的第 i 层上最多有2^{i-1}个节点
  2. 若规定只有根结点的二叉树的深度为,则深度为K的二叉树的最大结点数是2^{k}-1
  3. 对任何一棵二叉树, 如果其叶结点个数为 n0 , 度为2的非叶结点个数为 n2 ,则有 n0=n2+1 
  4.  具有 n 个结点的完全二叉树的深度 k \log _{2}^{}\textrm{}(n+1)
  5. 对于具有 n 个结点的完全二叉树,如果按照从上至下从左至右的顺序对所有节点从0开始编号,则对于序号为 i 的结点有:若i>0,双亲序号:(i-1)/2;i=0,i为根结点编号,无双亲结点;若2i+1<n,左孩子序号:2i+1,否则无左孩子;若2i+2<n,右孩子序号:2i+2,否则无右孩

五.二叉树的存储

对于任意一个节点,我们最多只能知道它的左右孩子节点和根节点,以及自己保存的数据,由此我们引申出许多种表示二叉树的方法,常见的有孩子表示法孩子双亲表示法兄弟节点表示法...

// 孩子表示法
class Node {int val; // 数据域Node left; // 左孩子的引用,常常代表左孩子为根的整棵左子树Node right; // 右孩子的引用,常常代表右孩子为根的整棵右子树
}// 孩子双亲表示法
class Node {int val; // 数据域Node left; // 左孩子的引用,常常代表左孩子为根的整棵左子树Node right; // 右孩子的引用,常常代表右孩子为根的整棵右子树Node parent; // 当前节点的根节点
}

笔者以下图举例:

 

我们使用孩子表示法,然后依次按照图示组成一颗二叉树(后文的遍历都是基于此树)

public class MyBinaryTree {public class TreeNode {public char val;//记录当前节点的值public TreeNode leftNode;//记录当前节点的左孩子节点public TreeNode rightNode;//记录当前节点的右孩子节点public TreeNode(char val) {//初始化节点的值this.val = val;}}//生成每一个节点,然后连起来public TreeNode CreatTree() {TreeNode A = new TreeNode('A');TreeNode B = new TreeNode('B');TreeNode C = new TreeNode('C');TreeNode D = new TreeNode('D');TreeNode E = new TreeNode('E');TreeNode F = new TreeNode('F');TreeNode G = new TreeNode('G');TreeNode H = new TreeNode('H');//依次按照图示连起来A.leftNode = B;A.rightNode = C;B.leftNode = D;C.leftNode = E;C.rightNode = F;//最后返回根节点return A;}
}

六.二叉树的遍历

二叉树的遍历是指按照一定的规则,将二叉树中的所有节点访问一次,并且每个节点只访问一次。常见的二叉树遍历方式有前序遍历中序遍历后序遍历

前序遍历

前序遍历(preorder traversal):先访问根节点,然后遍历左子树,最后遍历右子树。具体步骤如下:

  1. 访问根节点
  2. 前序遍历左子树
  3. 前序遍历右子树 

代码实现如下:

    //前序遍历public void preOrder(TreeNode root) {if (root == null) {return;//空树不需要遍历}System.out.print(root.val + " ");//访问根节点preOrder(root.leftNode);//前序遍历左子树preOrder(root.rightNode);//前序遍历右子树}

对于上述的代码,程序运行起来的具体逻辑是如下图这样的,反复的递归和回退进行实现

 

中序遍历 

中序遍历(inorder traversal):先遍历左子树,然后访问根节点,最后遍历右子树。具体步骤如下:

  1. 中序遍历左子树
  2. 访问根节点
  3. 中序遍历右子树

代码实现如下:

    //中序遍历public void inOrder(TreeNode root) {if (root == null) {return;//空树不需要遍历}inOrder(root.leftNode);//中序遍历左子树System.out.print(root.val + " ");//访问根节点inOrder(root.rightNode);//中序遍历右子树}

后序遍历 

后序遍历(postorder traversal):先遍历左子树,然后遍历右子树,最后访问根节点。具体步骤如下:

  1. 后序遍历左子树
  2. 后序遍历右子树
  3. 访问根节点

代码实现如下:

    //后序遍历public void postOrder(TreeNode root) {if (root == null) {return;//空树不需要遍历}postOrder(root.leftNode);//后序遍历左子树postOrder(root.rightNode);//后序遍历右子树System.out.print(root.val + " ");//访问根节点}

我们可以写个测试来看看遍历的结果:

public class Test {public static void main(String[] args) {MyBinaryTree myBinaryTree = new MyBinaryTree();MyBinaryTree.TreeNode rootNode = myBinaryTree.CreatTree();System.out.println();System.out.println("前序遍历:");myBinaryTree.preOrder(rootNode);System.out.println();System.out.println("中序遍历:");myBinaryTree.inOrder(rootNode);System.out.println();System.out.println("后序遍历:");myBinaryTree.postOrder(rootNode);}
}

输出:

也就是说:

其实不管是前序,中序,后序遍历,他们整体的搜索过程都是一样的,不同的地方在于对当前根节点的处理时间不一样:前序遍历是先处理根节点;中序遍历是先遍历当前节点的左子树再处理当前根节点;而后序遍历则是最后再处理根节点,就像下图一样

以上是三种最基本的二叉树遍历方式。除了这三种,还有一些其他的二叉树遍历方式,比如层序遍历螺旋遍历等。不同的遍历方式适用于不同的场景和问题,可以根据具体的需求选择合适的遍历方式。




  本次的分享就到此为止了,希望我的分享能给您带来帮助,也欢迎大家三连支持,你们的点赞就是博主更新最大的动力!如有不同意见,欢迎评论区积极讨论交流,让我们一起学习进步!有相关问题也可以私信博主,评论区和私信都会认真查看的,我们下次再见

相关文章:

数据结构:图文详解 树与二叉树(树与二叉树的概念和性质,存储,遍历)

目录 一.树的概念 二.树中重要的概念 三.二叉树的概念 满二叉树 完全二叉树 四.二叉树的性质 五.二叉树的存储 六.二叉树的遍历 前序遍历 中序遍历 后序遍历 一.树的概念 树是一种非线性数据结构&#xff0c;它由节点和边组成。树的每个节点可以有零个或多个子节点…...

DM工作笔记-在windows下对DM7进行库还原恢复

提供了这些备份数据 在windows平台上&#xff0c;将这些备份数据还原到新库中。 首先实例得先停掉&#xff1a; 使用的软件console.exe&#xff1a; 重要步骤&#xff1a;①获取备份&#xff1b;②还原&#xff1b;③恢复 记住DMAP方式这个不要勾选&#xff0c;然后再获取备份…...

STM32软硬件CRC测速对比

硬件CRC配置 以及软硬件CRC速度对比 使用CUBEMX配置默认使用的是CRC32&#xff0c;从库中可以看出这一点 HAL库提供了以下两个计算函数 HAL_CRC_Accumulate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength); 这个函数用于在已有的CRC校验结果的基础上累积…...

第九部分 图论

目录 例 相关概念 握手定理 例1 图的度数列 例 无向图的连通性 无向图的连通度 例2 例3 有向图D如图所示&#xff0c;求 A, A2, A3, A4&#xff0c;并回答诸问题&#xff1a; 中间有几章这里没有写&#xff0c;感兴趣可以自己去学&#xff0c;组合数学跟高中差不多&#xff0c…...

如何用java实现对java虚拟机的性能监控?

要使用Java实现对Java虚拟机&#xff08;JVM&#xff09;的性能监控&#xff0c;可以使用Java Management Extensions&#xff08;JMX&#xff09;来获取和监控JVM的各种指标。以下是一个简单的示例代码&#xff0c;演示如何使用JMX监控JVM的内存使用情况&#xff1a; import …...

电路设计(7)——窗口比较器的multism仿真

1.功能设计 构建一个窗口比较器的电路&#xff0c;在输入电压大于3.5v&#xff0c;小于0.8v时&#xff0c;蜂鸣器报警&#xff0c;输入电压在0.8v到3.5v之间时&#xff0c;不报警。 整体电路如下&#xff1a; 2.设计思路 在输入端&#xff0c;采取电阻分压的方式&#xff0c;输…...

前端已死?探讨人工智能与低代码对前端的影响

文章目录 每日一句正能量前言前端行业究竟是好是坏&#xff1f;数字化转型的当下前端工程师该何去何从&#xff1f; 想要入行前端先认清这三个事实 后记 每日一句正能量 人的结构就是相互支撑&#xff0c;众人的事业需要每个人的参与。 前言 随着人工智能和低代码的崛起&#…...

树莓派,opencv,Picamera2利用舵机云台追踪人脸(PID控制)

一、需要准备的硬件 Raspiberry Pi 4b两个SG90 180度舵机&#xff08;注意舵机的角度&#xff0c;最好是180度且带限位的&#xff0c;切勿选360度舵机&#xff09;二自由度舵机云台&#xff08;如下图&#xff09;Raspiberry CSI 摄像头 组装后的效果&#xff1a; 二、项目目…...

uniapp中推出当前微信小程序

uni.exitMiniProgram() 通过代码直接退出当前小程序 uni.exitMiniProgram({success: function() {console.log(退出小程序成功);},fail: function(err) {console.log(退出小程序失败, err);} })...

AndroidStudio无法新建aidl文件解决办法

我用的 AS 版本是 Android Studio Giraffe | 2022.3.1 Build #AI-223.8836.35.2231.10406996, built on June 29, 2023 右键新建 aidl 文件&#xff0c; 提示 (AIDL File)Requires setting the buildFeatures.aidl to true in the build file 解决办法 修改 app 的 build.…...

java爬虫(jsoup)如何设置HTTP代理ip爬数据

目录 前言 什么是HTTP代理IP 使用Jsoup设置HTTP代理IP的步骤 1. 导入Jsoup依赖 2. 创建HttpProxy类 3. 设置代理服务器 4. 使用Jsoup进行爬取 结论 前言 在Java中使用Jsoup进行网络爬虫操作时&#xff0c;有时需要使用HTTP代理IP来爬取数据。本文将介绍如何使用Jsoup设…...

ZooKeeper Client API 安装及使用指北

下载 wget https://archive.apache.org/dist/zookeeper/zookeeper-3.5.4-beta/zookeeper-3.5.4-beta.tar.gz解压 tar -zxf zookeeper-3.5.4-beta.tar.gz安装 cd zookeeper-3.5.4-beta/src/c/ ./configure make sudo make install到 make 这一步大概率会出现报错&#xff1a;…...

本机ping不通虚拟机

windows下finall shell连不上虚拟机了&#xff0c;之前是可以的&#xff0c;然后ping虚拟机&#xff0c;发现也ping不通&#xff0c;随后到处找问题。 在本地部分&#xff0c;控制面板 ——>网络和Internet——>网络连接 &#xff0c; 可以看到 VMnet1和Vmnet8虽然都是已…...

Linux cfdisk命令

Linux cfdisk命令用于磁盘分区。 cfdisk是用来磁盘分区的程序&#xff0c;它十分类似DOS的fdisk&#xff0c;具有互动式操作界面而非传统fdisk的问答式界面&#xff0c;您可以轻易地利用方向键来操控分区操作。 语法 cfdisk [-avz][-c <柱面数目>-h <磁头数目>-…...

实用学习网站和资料

github:https://github.com/GitHubDaily/GitHubDaily Linux操作手册&#xff1a; GitHub - abarrak/linux-sysops-handbook: Essentials of Linux system administration. 从零开始制作一个操作系统&#xff1a; GitHub - ruiers/os-tutorial-cn: 从零开始编写一个操作系统…...

【已解决】c++qt如何制作翻译供程序调用

本博文源于笔者正在编写的工具需要创建翻译文件&#xff0c;恰好将qt如何进行翻译&#xff0c;从零到结果进行读者查阅&#xff0c;并非常推荐读者进行收藏点赞&#xff0c;因为步步都很清晰&#xff0c;堪称胎教式c制作&#xff0c;而且内容还包括如何部署在windows下。堪称值…...

DPDK单步跟踪(3)-如何利用visual studio 2019和visual gdb来单步调试dpdk

准备工作 因为时间的关系&#xff0c;我想到哪说到哪&#xff0c;可能没那么高的完成度。 但其实有心的人&#xff0c;看到这个标题&#xff0c;就关了本文自己能做了。 why和how to build debug version DPDK,见前两篇。这里我们准备开始。 首先&#xff0c;你有一台linux机…...

Python爬虫---解析---BeautifulSoup

BeautifulSoup简称&#xff1a;bs4 作用&#xff1a;解析和提取数据 1. 安装&#xff1a;pip install bs4 或pip install bs4 -i https://pypi.douban.com/simple&#xff08;使用国内镜像下载&#xff09; 注意&#xff1a;需要安装在python解释器相同的位置,例如&#xf…...

Argument list too long when copying files

for i in /path/to/dir/*; do cp "$i" /path/to/other/dir/; done...

configure

configure 配置软件./configure --prefix$PWD/output CCaarch64-linux-gcc --hostaarch64-linux --enable-shared --enable-staticconfig.sub 文件 这个文件用于确定主机系统的类型&#xff0c;并返回与该系统相关的标识符。它包含一系列 shell 函数&#xff0c;用于检测主机…...

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

【WiFi帧结构】

文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成&#xff1a;MAC头部frame bodyFCS&#xff0c;其中MAC是固定格式的&#xff0c;frame body是可变长度。 MAC头部有frame control&#xff0c;duration&#xff0c;address1&#xff0c;address2&#xff0c;addre…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解

【关注我&#xff0c;后续持续新增专题博文&#xff0c;谢谢&#xff01;&#xff01;&#xff01;】 上一篇我们讲了&#xff1a; 这一篇我们开始讲&#xff1a; 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下&#xff1a; 一、场景操作步骤 操作步…...

CentOS下的分布式内存计算Spark环境部署

一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架&#xff0c;相比 MapReduce 具有以下核心优势&#xff1a; 内存计算&#xff1a;数据可常驻内存&#xff0c;迭代计算性能提升 10-100 倍&#xff08;文档段落&#xff1a;3-79…...

Cinnamon修改面板小工具图标

Cinnamon开始菜单-CSDN博客 设置模块都是做好的&#xff0c;比GNOME简单得多&#xff01; 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

接口自动化测试:HttpRunner基础

相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具&#xff0c;支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议&#xff0c;涵盖接口测试、性能测试、数字体验监测等测试类型…...

作为测试我们应该关注redis哪些方面

1、功能测试 数据结构操作&#xff1a;验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化&#xff1a;测试aof和aof持久化机制&#xff0c;确保数据在开启后正确恢复。 事务&#xff1a;检查事务的原子性和回滚机制。 发布订阅&#xff1a;确保消息正确传递。 2、性…...

pycharm 设置环境出错

pycharm 设置环境出错 pycharm 新建项目&#xff0c;设置虚拟环境&#xff0c;出错 pycharm 出错 Cannot open Local Failed to start [powershell.exe, -NoExit, -ExecutionPolicy, Bypass, -File, C:\Program Files\JetBrains\PyCharm 2024.1.3\plugins\terminal\shell-int…...

【若依】框架项目部署笔记

参考【SpringBoot】【Vue】项目部署_no main manifest attribute, in springboot-0.0.1-sn-CSDN博客 多一个redis安装 准备工作&#xff1a; 压缩包下载&#xff1a;http://download.redis.io/releases 1. 上传压缩包&#xff0c;并进入压缩包所在目录&#xff0c;解压到目标…...

C++ 类基础:封装、继承、多态与多线程模板实现

前言 C 是一门强大的面向对象编程语言&#xff0c;而类&#xff08;Class&#xff09;作为其核心特性之一&#xff0c;是理解和使用 C 的关键。本文将深入探讨 C 类的基本特性&#xff0c;包括封装、继承和多态&#xff0c;同时讨论类中的权限控制&#xff0c;并展示如何使用类…...