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

树的应用 —— 二叉树遍历【先序、中序、后序】

树的应用 —— 二叉树遍历【先序、中序、后序】

二叉树的遍历就是按某条搜索路径访问二叉树中的每个节点一次且仅一次。

访问的含义很广,例如输出、查找、插入、删除、修改、运算等,都可以被称为访问。

遍历是有顺序的【如何进行二叉树的遍历】

一棵二叉树是由根、左子树、右子树构成的,如下图所示。

在这里插入图片描述

那么按照根、左子树、右子树的访问先后顺序不同,可以有6种遍历方案:DLR、LDR、LRD、DRL、RDL、RLD,

如果限定先左后右(先左子树后右子树),则只有前3种遍历方案:DLR、LDR、LRD。

按照根的访问顺序不同,根在前面的被称为先序遍历(DLR),根在中间的被称为中序遍历(LDR),根在最后的被称为后序遍历(LRD)。

因为树的定义本身就是递归的,因此树和二叉树的基本操作用递归算法很容易实现。

【先序遍历】【根左右】

先序遍历指先访问根,然后先序遍历左子树,再先序遍历右子树,即DLR。

[算法步骤]

如果二叉树为空,则为空操作,否则:

①访问根节点;

②先序遍历左子树;

③先序遍历右子树。

[先序遍历秘籍:访问根,先序遍历左子树,在左子树为空或已遍历时才可以遍历右子树。]

[完美图解]

一棵二叉树的先序遍历过程如下。

① 访问根节点A,然后先序遍历A的左子树。

在这里插入图片描述

② 访问根节点B,然后先序遍历B的左子树。

在这里插入图片描述

③ 访问根节点D,然后先序遍历D的左子树,D的左子树为空,什么也不做,返回。

在这里插入图片描述

④ 先序遍历D的右子树,D的右子树为空,什么也不做,返回B。

在这里插入图片描述

⑤ 先序遍历B的右子树。

在这里插入图片描述

⑥ 访问根节点E,先序遍历E的左子树,E的左子树为空,什么也不做,返回。先序遍历E的右子树,E的右子树为空,什么也不做,返回A。

在这里插入图片描述

⑦ 先序遍历A的右子树。

在这里插入图片描述

⑧ 访问根节点C,然后先序遍历C的左子树。

在这里插入图片描述

⑨ 访问根节点F,然后先序遍历F的左子树,F的左子树为空,什么也不做,返回。

在这里插入图片描述

⑩ 先序遍历F的右子树。

在这里插入图片描述

⑪ 访问根节点G,先序遍历G的左子树,G的左子树为空,什么也不做,返回。先序遍历G的右子树,G的右子树为空,什么也不做,返回C。

在这里插入图片描述

⑫ 先序遍历C的右子树,C的右子树为空,什么也不做,遍历结束。

在这里插入图片描述

所以先序遍历序列为 ABDECFG。

[算法代码]

void preorder(Btree T){ //先序遍历
	if(T){
		cout << T->data << " ";
		preorder(T->lchild);
		preorder(T->rchild);
	}
}

【中序遍历】【左根右】

中序遍历指中序遍历左子树,然后访问根,再中序遍历右子树,即LDR。

[算法步骤]

如果二叉树为空,则为空操作,否则

①中序遍历左子树;

②访问根节点;

③中序遍历右子树。

[中序遍历秘籍]

中序遍历左子树,在左子树为空或已遍历时才可以访问根,中序遍历右子树。

[完美图解]

一棵二叉树的中序遍历过程如下。

① 中序遍历A的左子树,如下图所示。

在这里插入图片描述

② 中序遍历B的左子树,如下图所示

在这里插入图片描述

③ 中序遍历D的左子树,D的左子树为空,则访问D,然后中序遍历D的右子树,D的右子树也为空,则返回B,如下图所示。

在这里插入图片描述

④ 访问B,然后中序遍历B的右子树,如下图所示。

在这里插入图片描述

⑤ 中序遍历E的左子树,E的左子树为空,则访问E,然后中序遍历E的右子树,E的右子树也为空,则返回A,如下图所示。

在这里插入图片描述

⑥ 访问A,然后中序遍历A的右子树,如下图所示。

在这里插入图片描述

⑦ 中序遍历C的左子树,如下图所示。

在这里插入图片描述

⑧ 中序遍历F的左子树,F的左子树为空,则访问F,然后中序遍历F的右子树。

在这里插入图片描述

⑨ 中序遍历G的左子树,G的左子树为空,则访问G,然后中序遍历G的右子树,G的右子树也为空,则返回C,如下图所示。

在这里插入图片描述

⑩ 访问C,然后中序遍历C的右子树,G的右子树为空,遍历结束,如下图所示。

在这里插入图片描述

所以中序遍历序列为 DBEAFGC。

[算法代码]

void inorder(){ //中序遍历
	if(T){
		inorder(T->lchild);
		cout << T-data << " ";
		inorder(T->rchild);
	}
}

【后序遍历】【左右根】

后序遍历指后序遍历左子树,后序遍历右子树,然后访问根,即LRD。

[算法步骤]

如果二叉树为空,则空操作,否则

①后序遍历左子树;

②后序遍历右子树;

③访问根节点。

[后序遍历秘籍]

后序遍历左子树,后序遍历右子树,在左子树、右子树为空或已遍历时才可以访问根。

[完美图解]

一棵二叉树的后序遍历过程如下。

① 后序遍历A的左子树。

在这里插入图片描述

② 后序遍历B的左子树。

在这里插入图片描述

③ 后序遍历D的左子树,D的左子树为空,后序遍历D的右子树,D的右子树也为空,则访问D,返回B。

在这里插入图片描述

④ 后序遍历B的右子树。

在这里插入图片描述

⑤ 后序遍历E的左子树,E的左子树为空,后序遍历E的右子树,E的右子树也为空,则访问E,此时B的左、右子树都已遍历,访问B,返回A。

在这里插入图片描述

⑥ 后序遍历A的右子树。

在这里插入图片描述

⑦ 后序遍历C的左子树。

在这里插入图片描述

⑧ 后序遍历F的左子树,F的左子树为空,后序遍历F的右子树。

在这里插入图片描述

⑨ 后序遍历G的左子树,G的左子树为空,后序遍历G的右子树,G的右子树也为空,则访问G,此时F的左、右子树都已遍历,访问F,然后返回C。

在这里插入图片描述

⑩ 后序遍历C的右子树,C的右子树为空,此时C的左、右子树都已遍历,访问C,此时A的左、右子树都已遍历,访问A,遍历结束。

在这里插入图片描述

所以后序遍历序列为 DEBGFCA。

[算法代码]

void posorder(){ //后序遍历
	if(T){
		posorder(T->lchild);
		posorder(T->rchild);
		cout << T->data << " ";
	}
}

所以

二叉树遍历的代码非常简单明了,“cout<data;”语句在前面就是先序,在中间就是中序,在后面就是后序。

【使用投影法快速得到遍历序列】

① 中序遍历

中序遍历就像在无风的情况下,顺序为左子树、根、右子树,太阳直射,将所有节点都投影到地上。

一棵二叉树,其中序序列投影如下图所示。中序遍历序列为DBEAFGC。

在这里插入图片描述

② 先序遍历

先序遍历就像在左边大风的情况下,将二叉树树枝刮向右方,且顺序为根、左子树、右子树,太阳直射,将所有节点都投影到地上。

一棵二叉树,其先序遍历投影序列如下图所示。先序遍历序列为ABDECFG。

在这里插入图片描述

③ 后序遍历

后序遍历就像在右边大风的情况下,将二叉树树枝刮向左方,且顺序为左子树、右子树、根,太阳直射,将所有节点都投影到地上。

一棵二叉树,其后序遍历投影序列如下图所示。后序遍历序列为DEBGFCA。

在这里插入图片描述

相关文章:

  • JUC-集合线程安全-HashSet和HashMap线程不安全
  • ES6解构赋值(数组,对象,函数)
  • Codeforces Round #791 (Div. 2)
  • C++类和对象(上)
  • 使用IDEA打包发布SpringBoot并部署到云服务器
  • 常用ADB命令
  • springboot二手交易平台 毕业设计-附源码290915
  • Unable to find instance for system-app
  • Android LruCache
  • docker安装GBase 8s(一)
  • 软考:信息安全工程师2
  • 微软Win11 22H2 22621.607(KB5017389)RP预览版发布!
  • RK3399平台开发系列讲解(USB篇)USB设备基础结构
  • java计算机毕业设计商超销售系统源代码+数据库+系统+lw文档
  • 阿里云视频点播-->>>阿里云媒资上传工具类及配置
  • ES6简单总结(搭配简单的讲解和小案例)
  • JS+CSS实现数字滚动
  • node 版本过低
  • scala基础语法(二)
  • Shell编程
  • Three.js 再探 - 写一个跳一跳极简版游戏
  • TypeScript实现数据结构(一)栈,队列,链表
  • 阿里云爬虫风险管理产品商业化,为云端流量保驾护航
  • 基于游标的分页接口实现
  • 记一次删除Git记录中的大文件的过程
  • 今年的LC3大会没了?
  • 理解IaaS, PaaS, SaaS等云模型 (Cloud Models)
  • 前端技术周刊 2018-12-10:前端自动化测试
  • 世界上最简单的无等待算法(getAndIncrement)
  • 思考 CSS 架构
  • 微信开源mars源码分析1—上层samples分析
  • 用element的upload组件实现多图片上传和压缩
  • 优化 Vue 项目编译文件大小
  • 字符串匹配基础上
  • MiKTeX could not find the script engine ‘perl.exe‘ which is required to execute ‘latexmk‘.
  • Hibernate主键生成策略及选择
  • Redis4.x新特性 -- 萌萌的MEMORY DOCTOR
  • ​用户画像从0到100的构建思路
  • # 手柄编程_北通阿修罗3动手评:一款兼具功能、操控性的电竞手柄
  • ###C语言程序设计-----C语言学习(6)#
  • (1)虚拟机的安装与使用,linux系统安装
  • (2)STL算法之元素计数
  • (4)事件处理——(7)简单事件(Simple events)
  • (AtCoder Beginner Contest 340) -- F - S = 1 -- 题解
  • (Ruby)Ubuntu12.04安装Rails环境
  • (博弈 sg入门)kiki's game -- hdu -- 2147
  • (超详细)语音信号处理之特征提取
  • (理论篇)httpmoudle和httphandler一览
  • (入门自用)--C++--抽象类--多态原理--虚表--1020
  • (一)【Jmeter】JDK及Jmeter的安装部署及简单配置
  • *1 计算机基础和操作系统基础及几大协议
  • .net 打包工具_pyinstaller打包的exe太大?你需要站在巨人的肩膀上-VC++才是王道
  • .net 桌面开发 运行一阵子就自动关闭_聊城旋转门家用价格大约是多少,全自动旋转门,期待合作...
  • .NET大文件上传知识整理
  • .NET牛人应该知道些什么(2):中级.NET开发人员