当前位置: 首页 > 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;用于检测主机…...

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周&#xff0c;有很多同学在写期末Java web作业时&#xff0c;运行tomcat出现乱码问题&#xff0c;经过多次解决与研究&#xff0c;我做了如下整理&#xff1a; 原因&#xff1a; IDEA本身编码与tomcat的编码与Windows编码不同导致&#xff0c;Windows 系统控制台…...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接&#xff0c;私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!

一、引言 在数据驱动的背景下&#xff0c;知识图谱凭借其高效的信息组织能力&#xff0c;正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合&#xff0c;探讨知识图谱开发的实现细节&#xff0c;帮助读者掌握该技术栈在实际项目中的落地方法。 …...

多种风格导航菜单 HTML 实现(附源码)

下面我将为您展示 6 种不同风格的导航菜单实现&#xff0c;每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

听写流程自动化实践,轻量级教育辅助

随着智能教育工具的发展&#xff0c;越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式&#xff0c;也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建&#xff0c;…...

用机器学习破解新能源领域的“弃风”难题

音乐发烧友深有体会&#xff0c;玩音乐的本质就是玩电网。火电声音偏暖&#xff0c;水电偏冷&#xff0c;风电偏空旷。至于太阳能发的电&#xff0c;则略显朦胧和单薄。 不知你是否有感觉&#xff0c;近两年家里的音响声音越来越冷&#xff0c;听起来越来越单薄&#xff1f; —…...

JVM 内存结构 详解

内存结构 运行时数据区&#xff1a; Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器&#xff1a; ​ 线程私有&#xff0c;程序控制流的指示器&#xff0c;分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 ​ 每个线程都有一个程序计数…...

在 Spring Boot 中使用 JSP

jsp&#xff1f; 好多年没用了。重新整一下 还费了点时间&#xff0c;记录一下。 项目结构&#xff1a; pom: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://ww…...

Leetcode33( 搜索旋转排序数组)

题目表述 整数数组 nums 按升序排列&#xff0c;数组中的值 互不相同 。 在传递给函数之前&#xff0c;nums 在预先未知的某个下标 k&#xff08;0 < k < nums.length&#xff09;上进行了 旋转&#xff0c;使数组变为 [nums[k], nums[k1], …, nums[n-1], nums[0], nu…...

从零开始了解数据采集(二十八)——制造业数字孪生

近年来&#xff0c;我国的工业领域正经历一场前所未有的数字化变革&#xff0c;从“双碳目标”到工业互联网平台的推广&#xff0c;国家政策和市场需求共同推动了制造业的升级。在这场变革中&#xff0c;数字孪生技术成为备受关注的关键工具&#xff0c;它不仅让企业“看见”设…...