【数据结构】二叉树的前中后序遍历(C语言)

文章目录

  • 什么是二叉树
    • 树相关的概念
    • 树的表示形式
    • 特殊的二叉树
    • 如何创造出一棵二叉树
    • 二叉树的遍历
      • 先序遍历(前序遍历)
      • 中序遍历
      • 后序遍历
    • 总结

什么是二叉树

[二叉树] 顾名思义就是有两个分支节点的树,不仅如此,除了叶子外的所有节点都具有两个分支节点;
由于结构像一棵倒立的树,顾名思义为二叉树

在这里插入图片描述

如下图所示,该图即为一棵野生的二叉树

在这里插入图片描述

既然二叉树为树,固然有着和树一样的部分(叶子、根、分支…)
这些也成为了树相关的概念;


树相关的概念

  • 叶子节点或者终端节点

叶子节点或终端节点,顾名思义就是最底端的节点,该节点不存在分支,故被称为叶子;

在这里插入图片描述


  • 节点的度

节点的度即为一个节点含有的子树成为该节点的度,如图所示,节点C的度为3;

在这里插入图片描述


  • 双亲结点(父节点)

若是一个节点存在子节点则该节点成为该子节点的父节点;如上图所示,A节点既是B的父节点,也是C的父节点;


  • 兄弟节点

具有相同父节点的节点成称为兄弟节点,“双亲结点”中所提到的“A结点既是B的父节点,也是C的父结点”处中的BC节点即为兄弟节点。


  • 树的度

树的度即为一棵树中,最大的节点的度,如“结点的度”中的C节点,该节点为整棵树中度最大的结点为3,故该树的度为3;


  • 树的高度或深度

树中结点的最大层次即为树的高度,如上图所示,树的高度为3;


  • 堂兄弟节点

双亲在同一层的节点互为堂兄弟,如上图所示,E节点和F节点护卫堂兄弟节点;


  • 节点的祖先

从根到节点所经分支上的所有节点,如上图所示,A节点为所有节点的祖先;


  • 子孙

以某节点为根的子树中任意一个节点都称为该节点的子孙
如上图所示,除A以外的所有其他节点都为A节点的子孙;


  • 森林

由m(m>0)棵互不相交的树的集合称为森林;


树的表示形式

树的结构与线性表相比就会更加复杂,既要保存值域,同时也要保存树中节点与节点之间的关系;在树中有许多的表示方法(双亲表示法、孩子表示法、孩子双亲表示法、孩子兄弟表示法等等),在此就不做过多赘述;

既然树的结构如此复杂,那对于真正实际中,树有什么应用呢?大家可以将计算机中的文件夹进行比较,从一个文件夹可以分支出很多个文件夹,文件夹内还可以继续存放文件夹,如此;
在Linux操作系统就应用了文件目录树,目录树的起点是根目录,Linux文件系统中的每一文件在此目录树中的文件名都是独一无二的,因为其包含从根目录开始的完整路径;
同时在很多算法中,都运用到了树;


特殊的二叉树

二叉树在树中也算是一个比较特殊的树种,但在二叉树中也存在着特殊的二叉树,即为完全二叉树与满二叉树

  • 满二叉树
    一个二叉树,如果每一层的节点树都达到最大值,则这个二叉树就是满二叉树;也就是说,如果一个二叉树的层数为k,且节点总数是2^k-1,则它就是满二叉树;
  • 完全二叉树
    完全二叉树是一种效率很高的树,是由满二叉树引申出来的。对于深度为k的,有n个节点的二叉树,当且仅当其每个节点都与深度k的满二叉树中编号从1至n的节点一一对应时称为完全二叉树,同时满二叉树也是一种特殊的完全二叉树。
    在这里插入图片描述

如何创造出一棵二叉树

在不使用任何算法的前提下若是想得到一棵二叉树可以使用比较简单粗暴的方式:

将各个节点创建并将每个节点连接在一起(该方法适用于任何一种树);

根据树的结构我们可以得知,树既要保存值域,同时也要保存节点之间的关系,又因为为二叉树(每个节点必有两个分支)

假设需要创建一个如图所示的二叉树
在这里插入图片描述

在此处可以定义一个结构体,并在结构体内存放结构体指针用来存放左右两个子树,同时创建一个成员变量用来存放所需要存储的值域

typedef char BTDataType;
typedef struct BinaryNode
{struct BinaryNode*left;struct BinaryNode*right;BTDataType a;
}BTNode;

根据图所示可知,A节点的子节点为B、C;
B节点的子节点为D、E;
C节点的子节点为F、G;

	int main(){BTNode q1;BTNode q2;BTNode q3;BTNode q4;BTNode q5;BTNode q6;BTNode q7;q1.a = 'A';q2.a = 'B';q3.a = 'C';q4.a = 'D';q5.a = 'E';q6.a = 'F';q7.a = 'G';q1.left = &q2;q1.right = &q3;q2.left = &q4;q2.right = &q5;q3.left = &q6;q3.right = &q7;q4.left = q4.right = q5.left = q5.right =q6.left = q6.right = q7.left = q7.right =NULL;return 0;}

二叉树的遍历

二叉树的遍历分为先序遍历,中序遍历,后序遍历以及层序遍历

为什么会叫先中后,顾名思义,这里的先中后为遍历过程中根节点的访问顺序,一棵树的任意子树都可以看成根节点和子树;
至于层序遍历,即为一层一层的进行访问;

首先设存在一棵二叉树
在这里插入图片描述

先序遍历(前序遍历)

先序遍历的遍历方式为:根、左子树、右子树
按照该树可以得出,该树的前序遍历为:A,B,D,E,C,F,G

根据根、左子树、右子树的顺序可知,最先访问的必定是A节点,当A节点访问完即访问左子树,而左子树的根节点为B,B访问结束访问B的左子树,为D,D没有左右子树(为空)故返回访问B的右子树,E与D同理,而后B访问结束放回根节点A并访问A的右树,同理得出该树的前序遍历为 A,B,D,E,C,F,G

既然看图可以得出树的前序遍历,那在代码中如何表示出二叉树的前序遍历,该处只需要使用递归的方式,按照根、左、右的方式即可;

void BinaryTreePreOrder(BTNode*root)
{if(root==NULL){//当root为空时则表示该处无节点,即无存储有效数据,若是访问则会造成对空指针的非法解引用printf("NULL");return ;}printf("%c ",root->a);//若是不为空则打印出该节点内所存储的有效数据BinaryTreePreOrder(root->left);//访问该节点的左子树BinaryTreePreOrder(root->right);//访问该节点的右子树
}

如图所示
在这里插入图片描述


中序遍历

中序遍历的遍历顺序为:左子树、根、右子树
按照该树可得出中序遍历的结果为:D,B,E,A,F,C,G;

若是用代码方式表示即为:

void BinaryTreeInOrder(BTNode*root)
{if(root==NULL){//当root为空时则表示该处无节点,即无存储有效数据,若是访问则会造成对空指针的非法解引用printf("NULL");return;}printf("%c ",root->a);//若是不为空则打印出该节点内所存储的有效数据BinaryTreeInOrder(root->left);//访问该节点的左子树BinaryTreeInOrder(root->right);//访问该节点的右子树
}

后序遍历

中序遍历的遍历顺序为:左子树、右子树、根
按照该树可得出中序遍历的结果为:D,E,B,F,G,C,A;

若是用代码方式表示即为:

void BinaryTreePostOrder(BTNode*root)
{if(root==NULL){//当root为空时则表示该处无节点,即无存储有效数据,若是访问则会造成对空指针的非法解引用printf("NULL");return;}BinaryTreePostOrder(root->left);//访问该节点的左子树BinaryTreePostOrder(root->right);//访问该节点的右子树printf("%c ",root->a);//若是不为空则打印出该节点内所存储的有效数据}

总结

二叉树除了前中后序遍历以外还有一种遍历方式叫作层序遍历,可以使用队列的FIFO特性从而完成该遍历的实现;
在利用递归实现解决二叉树相关问题的过程中,可以根据实际情况选择相应的遍历方式从而以效率较高的方式解决问题;
所有的二叉树问题都可以将其分为两个子问题进行解决;

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

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

相关文章

RiProV2主题一级分类显示包含子分类的数量Ritheme主题美化WordPress美化类似的步骤

美化-RiProV2主题一级分类显示包含子分类的数量 WordPress主题一级分类页面显示包含子分类的数量 一级分类显示子分类相加的数量 原主题配置项 原来的RiProV2主题,虽然有个配置用来显示分类下的数量。 但是该数量有个问题,就是一级分类的数量显示不包含该一级分类下二级…

使用React的函数式组件实现一个具有过渡变化、刻度切换、点击高亮的柱状图DIY组件

本想使用业界大佬们开源的各种图表库(如:ECharts、G2可视化引擎、BizCharts ...),但是有的需求不仅要求有过渡变化,还要点击某个图高亮同时发送HTTP请求数据等功能,着实不知道怎么把canvas或svg绘制的图表弄…

【OJ比赛日历】快周末了,不来一场比赛吗? #07.15-07.21 #7场

CompHub[1] 实时聚合多平台的数据类(Kaggle、天池…)和OJ类(Leetcode、牛客…)比赛。本账号会推送最新的比赛消息,欢迎关注! 以下信息仅供参考,以比赛官网为准 目录 2023-07-15(周六) #3场比赛2023-07-16…

链上衍生品协议 ProsperEx:探索 RWA 叙事,打造 DeFi 变异黑马

“ProsperEx 本身背靠着具备潜力的链上衍生品赛道,同时也是 RWA 领域早期的布局者之一,其有望成为 Web2 世界与 Web3 世界的早期连接点,并具备广泛且规模性捕获用户的能力。” 从2020年DeFi之夏链上世界迎来了爆发后,链上衍生品赛…

Gateway网关组件(在Spring Cloud整合Gateway(idea19版本))

Spring Cloud Gateway官网:Spring Cloud Gateway 局域网中就有网关这个概念,局域网接收数据或发送数据都要通过网关,比如使用VMware虚拟机软件搭建虚拟机集群的时候,往往我们需要选择IP段中的⼀个IP作为网关地址,网关可以对请求进行控制,提升…

JAVA+Selenium最简单的处理登录弹窗的方式

在做自动化测试遇到需要处理登录弹窗情况,例如我的用户名为admin, 密码为admin, 那么想要登录http://10.10.168.1, 只需要使用以下链接访问即可立即登录, 并免除弹窗: http://账号:密码网址

Layui 简单介绍及入门

目录 一.Layui (国产品牌) 1.1 Layui是什么 二.比较layui和easyui,bootstrap的区别 2.1 layui和bootstrap的对比 2.2 layui和easyui对比 三.Layui入门 四.案例 一.Layui (国产品牌) 1.1 Layui是什么 用我的话来…

MySQL每日一练:多表查询——连接查询、子查询

目录 1、首先创建员工表emp和部门表dept: dept表: emp表: 2、插入数据: dept表: emp表: 3、 按条件查找 1、首先创建员工表emp和部门表dept: dept表: create table dept (…

【MQ】Windows上RabbitMQ的安装与启动

文章目录 下载Erlang安装RabbitMQ 下载Erlang RabbitMQ基于Erlang语言,因此使用RabbitMQ之前需要先安装Erlang,如下 Erlang语言下载 这里我是用的是25.2.2这个版本,我的机器是64bit的,所以下win64的即可。 下载完毕安装包之后点…

2023年软件测试岗位将会越来越少吗?

我的整体意见是测试岗位不会变少,反而相对于其他岗位会变的更重要一些。 首先纠正一个非常非常错误的观念。测试和测试开发是两个岗位?No,不是的。测试开发是属于测试的。 测试开发只不过是使用类似于开发的技术和能力,来达到测试…

【接口/性能测试】Jmeter引用 jar包的三种方式(详细)

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 实现对登录密码进…

idea-spring boot开发

安装maven与配置配置maven安装插件 已经装好了idea与jdk 安装maven与配置 下载地址: https://maven.apache.org/download.cgi 下载合适的版本 配置maven 打开设置: 直接搜索 :maven 配置变量: 此电脑->属性->高级系统设置->环境变量 新建系统变量 MAVEN_HOME&#xff…