数据结构学习——树形结构之递归遍历二叉树
目录
一. 什么是二叉树
二. 二叉树分类
2.1、完全二叉树
2.2、满二叉树
2.3、扩充二叉树
2.4、平衡二叉树
三. 二叉树的应用场景
四. 遍历方式
五. 为什么要研究遍历
六. 前序遍历
七. 中序遍历
八. 后序遍历
九. 数据结构专栏
一. 什么是二叉树
二叉树是每个结点最多有两个子树的树结构。通常子树被称作“左子树”和“右子树”。
二. 二叉树分类
2.1、完全二叉树
- 若设二叉树的高度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第h层有叶子结点,并且叶子结点都是从左到右依次排布,这就是完全二叉树。
- 一维数组可以作为完全二叉树的存储结构,堆排序使用的数据结构就是完全二叉树。
2.2、满二叉树
- 国际标准定义是除了叶结点外每一个结点都有左右子结点的二叉树
- 国内的定义是:除了叶结点外每一个结点都有左右子叶且叶子结点都处在最底层的二叉树。很显然,按照这个定义,上面的图示二叉树就不是满二叉树。
2.3、扩充二叉树
- 扩充二叉树是对已有二叉树的扩充,扩充后的二叉树的节点都变为度数为2的分支节点。也就是说,如果原节点的度数为2,则不变,度数为1,则增加一个分支,度数为0的叶子节点则增加两个分支。
2.4、平衡二叉树
- 是一棵空树或它的任意节点的左右两个子树的高度差的绝对值不超过1
三. 二叉树的应用场景
- 普通的二叉树,很难构成现实的应用场景,但因其简单,常用于学习研究,平衡二叉树则是实际应用比较多的。常见于快速匹配、搜索等方面。
- 常用的树有:AVL树、红黑树、B+树、Trie(字典)树。
1、AVL树: 最早的平衡二叉树之一。应用相对其他数据结构比较少。windows对进程地址空间的管理用到了AVL树。
2、红黑树: 平衡二叉树,广泛用在C++的STL中。如map和set都是用红黑树实现的。还有Linux文件管理。
3、B/B+树: 用在磁盘文件组织 数据索引和数据库索引。
4、Trie树(字典树): 用在统计和排序大量字符串,如自动机、M数据库索引。
四. 遍历方式
- 前序遍历:root -> left -> right
- 中序遍历:left -> root -> right
- 后序遍历:left ->right -> root
- 已知后序遍历和中序遍历,能确定前序遍历(也就是可以唯一确定一颗二叉树)。
- 已知前序遍历和中序遍历,能确定后序遍历(也就是可以唯一确定一颗二叉树)。
五. 为什么要研究遍历
当我们介绍数组、链表时,为什么没有着重研究他们的遍历过程呢?
二叉树的遍历又有什么特殊之处?
在计算机程序中,遍历本身是一个线性操作。所以遍历同样具有线性结构的数组或链表,是一件轻而易举的事。反观二叉树,是典型的非线性数据结构,遍历时需要把非线性关联的节点转化成一个线性的序列,以不同的方式来遍历,遍历出的序列顺序也不同。
那么,二叉树都有哪些遍历方式呢?
从节点之间位置关系的角度来看,二叉树的遍历分为3种。
- 前序遍历。
- 中序遍历。
- 后序遍历。
六. 前序遍历
前序遍历(DLR,lchild,data,rchild),是二叉树遍历的一种,也叫做先根遍历、先序遍历、前序周游,可记做根左右。前序遍历首先访问根结点然后遍历左子树,最后遍历右子树。
前序遍历首先访问根结点然后遍历左子树,最后遍历右子树。在遍历左、右子树时,仍然先访问 根结点,然后遍历左子树,最后遍历右子树。
若 二叉树为空则结束返回,否则:
(1)访问根结点。
(2)前序遍历左子树 。
(3)前序遍历右子树 。
需要注意的是:遍历左右子树时仍然采用前序遍历方法。
如图所示:
前序遍历结果:ABDECF
其实在遍历二叉树的时候有三次遍历, 比如前序遍历:A->B->D->D(D左子节点并返回到D)->D(D右子节点并返回到D)->B->E->E(左)->E(右)->->B->A->C->F->F(左)->F(右)->C->C(右),可以用递归的方式,递归的输出当前节点,然后递归的输出左子节点,最后递归的输出右子节点。直接看代码更能理解:
package test0910;public class Test {public static void main(String[] args) {TreeNode[] node = new TreeNode[10];// 以数组形式生成一棵完全二叉树for (int i = 0; i < 10; i++) {node[i] = new TreeNode(i);}for (int i = 0; i < 10; i++) {if (i * 2 + 1 < 10)node[i].left = node[i * 2 + 1];if (i * 2 + 2 < 10)node[i].right = node[i * 2 + 2];}preOrderRe(node[0]);}public static void preOrderRe(TreeNode biTree) {if (biTree == null)return;else {System.out.print(biTree.value + " ");preOrderRe(biTree.left);preOrderRe(biTree.right);}}
}//节点结构
class TreeNode {int value;TreeNode left;TreeNode right;TreeNode(int value) {this.value = value;}
}
七. 中序遍历
中序遍历(LDR)是 二叉树遍历的一种,也叫做 中根遍历、中序周游。在二叉树中,先左后根再右。巧记:左根右。
中序遍历首先遍历左子树,然后访问根结点,最后遍历右子树
若 二叉树为空则结束返回,
否则:
(1)中序遍历左子树
(2)访问根结点
(3)中序遍历右子树
如图所示:
中序遍历结果:DBEAFC
public class Test {public static void main(String[] args) {TreeNode[] node = new TreeNode[10];// 以数组形式生成一棵完全二叉树for (int i = 0; i < 10; i++) {node[i] = new TreeNode(i);}for (int i = 0; i < 10; i++) {if (i * 2 + 1 < 10)node[i].left = node[i * 2 + 1];if (i * 2 + 2 < 10)node[i].right = node[i * 2 + 2];}midOrderRe(node[0]);}public static void midOrderRe(TreeNode biTree) {// 中序遍历递归实现if (biTree == null)return;else {midOrderRe(biTree.left);System.out.print(biTree.value + " ");midOrderRe(biTree.right);}}
}// 节点结构
class TreeNode {int value;TreeNode left;TreeNode right;TreeNode(int value) {this.value = value;}
}
八. 后序遍历
后序遍历(LRD)是 二叉树遍历的一种,也叫做 后根遍历、后序周游,可记做左右根。后序遍历有 递归算法和非递归算法两种。在二叉树中,先左后右再根。巧记:左右根。
后序遍历首先遍历左子树,然后遍历右子树,最后访问根结点,在遍历左、右子树时,仍然先遍历左子树,然后遍历右子树,最后遍历根结点。即:
若 二叉树为空则结束返回,
否则:
(1)后序遍历左子树
(2)后序遍历右子树
(3)访问根结点
如图所示:
后序遍历结果:DEBFCA
public class Test {public static void main(String[] args) {// 以数组形式生成一棵完全二叉树TreeNode[] node = new TreeNode[10];for (int i = 0; i < 10; i++) {node[i] = new TreeNode(i);}for (int i = 0; i < 10; i++) {if (i * 2 + 1 < 10)node[i].left = node[i * 2 + 1];if (i * 2 + 2 < 10)node[i].right = node[i * 2 + 2];}postOrderRe(node[0]);}public static void postOrderRe(TreeNode biTree) {// 后序遍历递归实现if (biTree == null) {return;} else {postOrderRe(biTree.left);postOrderRe(biTree.right);System.out.print(biTree.value + " ");}}
}//节点结构
class TreeNode {int value;TreeNode left;TreeNode right;TreeNode(int value) {this.value = value;}
}
九. 数据结构专栏
https://blog.csdn.net/weixin_53919192/category_11908333.html?spm=1001.2014.3001.5482https://blog.csdn.net/weixin_53919192/category_11908333.html?spm=1001.2014.3001.5482
后文有介绍二叉树以及非递归遍历二叉树的内容,有兴趣的朋友可以去看看:树形结构之非递归遍历二叉树
数据结构学习——树形结构之递归遍历二叉树相关推荐
- 数据结构专题 | 先序非递归遍历二叉树
先序非递归遍历二叉树,主要是利用了栈的先进后出原理,用一个栈即可实现该算法,下面我们一起来看一下如何来实现吧 目录 先序建立二叉树 先序递归遍历二叉树 先序非递归遍历二叉树 先序建立二叉树 在进行先序 ...
- 数据结构: 中序非递归遍历二叉树
status InOrderTraverse(BiTree T,status (*visit)(TElementType e) { InitStack(s); p=T; while(p||!Stack ...
- 数据结构_非递归遍历二叉树(C语言)
数据结构总目录 非递归遍历二叉树 1. 图文解析 对于链式二叉树,如果要用非递归的方式进行前.中.后序遍历,则需要借助一个栈实现,而层序遍历则需要借助队列来实现. 构建如下二叉树: 非递归先序遍历 ( ...
- 栈模拟递归 遍历二叉树的正确写法
栈模拟递归 遍历二叉树的正确写法 二叉树的生成 树的层次遍历 前中后序遍历的递归实现 关于栈的实现 Reference 对于二叉树的生成,遍历,应该是树这个数据结构需要的基本功,只有真的理解了树的生成 ...
- js中树形结构的深度遍历与广度遍历
树形结构的深度遍历与广度遍历 定义 深度遍历:一个树形结构中,由一个数据分支全部遍历完才去遍历另外一个分支,直至全部数据遍历完成. 广度遍历:先遍历最外层的分支数据,然后一层一层的进行深入遍历,直至全 ...
- 【转】更简单的非递归遍历二叉树的方法
[转]更简单的非递归遍历二叉树的方法 解决二叉树的很多问题的方案都是基于对二叉树的遍历.遍历二叉树的前序,中序,后序三大方法算是计算机科班学生必写代码了.其递归遍历是人人都能信手拈来,可是在手生时写出 ...
- 更简单的非递归遍历二叉树
解决二叉树的很多问题的方案都是基于对二叉树的遍历.遍历二叉树的前序,中序,后序三大方法算是计算机科班学生必写代码了.其递归遍历是人人都能信手拈来,可是在手生时写出非递归遍历恐非易事.正因为并非易事,所 ...
- Python数据结构之树形结构——数组存储
Python数据结构之树形结构--数组存储 树:一种非线性结构,主要使用链表来存储,也可以使用数组存储. 本代码使用两种数组 元素数组:0,6,3,5,4,7,8,9,2 由于 0 索引不存储元素,所 ...
- 非递归遍历二叉树实现和理解
非递归遍历二叉树 1.前言 总所周知,二叉树的遍历分为先序遍历.中序遍历和后序遍历.遍历的顺序不同,则结果不同.而遍历方法也分递归和非递归.而二者的复杂度相同:时间复杂度为O(nlgn),空间复杂 ...
最新文章
- 计算机文化基础知识在未来工作中的应用论文,大学计算机文化基础论文范文2篇...
- 参与 Apache 顶级开源项目的 N 种方式,Apache Dubbo Samples SIG 成立!
- boost::fusion::transform_view用法的测试程序
- Android Custom View ----invalidate() 、postInvalidate() and requestLayout()
- MYSQL--三种锁
- 45分钟,411个中小品牌天猫双11实现新跨越
- [汇编与C语言关系]1.函数调用
- 一张思维导图,让正则表达式不再难懂
- 华为机试HJ4:字符串分隔
- 在Linux中smbfs文件系统的挂载
- 机器学习- 吴恩达Andrew Ng Week7 知识总结Support Vector Machines
- 免费10分钟邮箱上线啦~~
- 五大列级庄_波尔多1855年评定的列级名庄1-5级各有哪些?哪个产区的列级庄最多?...
- 计算机的cpu占用到多少会卡,CPU占用100%!PC卡顿原来可以这么解决:多场景多任务也流畅...
- 磁盘最优存储问题---Python
- 基于jsp+mysql+ssm酒店管理系统-计算机毕业设计
- [Erlang危机](3.1)常见过载情景
- 不符合正态分布的配对数据也有自己的统计方法。
- js手机号中间四位_为什么手机号码会影响我们?一个适合自己的手机号码有多重要?...
- 2018-11-16学习笔记 读论文Advantages of high quality SWIR bands for ocean colour processing: Examples from