数据结构(二十)二叉树的递归遍历算法
一、二叉树的遍历的定义
1.二叉树的遍历(traversing binary tree)是指从根结点出发,按照某种次序依次访问二叉树中所有结点,使得每个结点被访问依次且仅被访问依次。树的结点之间不存在唯一的前驱和后继关系,在访问一个结点后,下一个被访问的结点面临着不同的选择,因此,二叉树有多种遍历方法。这多种遍历方法,其实都是把非线性结构的二叉树编程线性序列,从而可以确定二叉树中某个指定结点在某种遍历序列中的前驱和后继。
2.二叉树遍历的性质:
- 已知前序遍历序列和中序遍历序列,可以唯一确定一棵二叉树。
- 已知后序遍历序列和中序遍历序列,可以唯一确定一棵二叉树。
- 已知前序遍历序列和后序遍历序列,不可以唯一确定一棵二叉树。
二、二叉树递归遍历方法
1.前序遍历
若二叉树为空,则空操作返回;否则
- 先访问根结点
- 前序遍历左子树
- 前序遍历右子树
(1)例如(双亲-左结点-右结点)
前序遍历的顺序为:ABDGHCEIF
(2)以下面的二叉树T为例分析代码:
1 /* 前序递归遍历T */ 2 void PreOrderTraverse(BiTree T) 3 { 4 if(T==NULL) 5 return; 6 printf("%c",T->data);/* 显示结点数据,可以更改为其它对结点操作 */ 7 PreOrderTraverse(T->lchild); /* 再先序遍历左子树 */ 8 PreOrderTraverse(T->rchild); /* 最后先序遍历右子树 */ 9 } 最后顺序为:ABDHKECFIGJ1.T为A, 二叉树T根结点不为null,执行第6行程序,打印A,进入T为A的72.T为A, 执行第7行程序,访问结点A的左孩子,执行第4行程序判断A的左孩子不为空,执行第6行程序,打印B,进入T为B的73.T为B, 执行第7行程序,访问结点B的左孩子,执行第4行程序判断B的左孩子不为空,执行第6行程序,打印D,进入T为D的74.T为D, 执行第7行程序,访问结点D的左孩子,执行第4行程序判断D的左孩子不为空,执行第6行程序,打印H,进入T为H的75.T为H, 执行第7行程序,访问结点H的左孩子,执行第4行程序判断H的左孩子为null,return掉,进入H的右孩子的86.T为H, 执行第8行程序,访问结点H的右孩子,执行第4行程序判断H的右孩子不为空,执行第6行程序,打印K,进入T为K的87.T为K, 执行第7行程序,访问结点K的左孩子,执行第4行程序判断K的左孩子为null,return掉,进入K的的88.T为K, 执行第8行程序,访问结点K的右孩子,执行第4行程序判断K的右孩子为null,return掉,执行完毕,到6,执行完毕,到4,进入T为D的89.T为D, 执行第8行程序,访问结点D的右孩子,执行第4行程序判断D的右孩子为null,return掉,执行完毕,到310.T为B,执行第8行程序,访问结点B的右孩子,执行第4行程序判断B的右孩子不为空,执行第6行程序,打印E,进入T为E的711.T为E,执行第7行程序,访问结点E的左孩子,执行第4行程序判断E的左孩子为null,return掉,进入E的812.T为E,执行第8行程序,访问结点E的左孩子,执行第4行程序判断E的右孩子为null,return掉,执行完毕,到10,执行完毕,到2,进入T为A的8...
2.中序遍历
若二叉树为空,则空操作返回;否则
- 中序遍历左子树
- 访问根结点
- 中序遍历右子树
(1)例如(左孩子-双亲-右孩子)
中序遍历的顺序为:GDHBAEICF
(2)以下面的二叉树T为例分析代码:
1 /*中序递归遍历T */ 2 void InOrderTraverse(BiTree T) 3 { 4 if(T==NULL) 5 return; 6 InOrderTraverse(T->lchild); /* 中序遍历左子树 */ 7 printf("%c",T->data); /* 显示结点数据,可以更改为其它对结点操作 */ 8 InOrderTraverse(T->rchild); /* 最后中序遍历右子树 */ 9 } 最后结果为:HKDBEAIFCGJ
1.T为A, 二叉树T根结点不为null,执行第6行程序,进入T为A的62.T为A, 执行第6行程序,访问结点A的左孩子,执行第4行程序判断A的左孩子不为空,进入T为B的63.T为B, 执行第6行程序,访问结点B的左孩子,执行第4行程序判断B的左孩子不为空,进入T为D的64.T为D, 执行第6行程序,访问结点D的左孩子,执行第4行程序判断D的左孩子不为空,进入T为H的65.T为H, 执行第6行程序,访问结点H的左孩子,执行第4行程序判断H的左孩子为空,return掉,到4,T为H,执行第7行程序,打印H,进入T为H的86.T为H, 执行第8行程序,访问结点H的右孩子,执行第4行程序判断H的右孩子不为空,进入T为K的67.T为K, 执行第6行程序,访问结点K的左孩子,执行第4行程序判断K的左孩子为空,return掉,到6,T为k,执行第7行程序,打印K,进入T为K的88.T为K, 执行第8行程序,访问结点K的右孩子,执行第4行程序判断K的右孩子为空,return掉,执行完毕,到6,执行完毕,到4,进入T为D的89.T为D, 执行第8行程序,访问结点D的右孩子,执行第4行程序判断D的右孩子为空,return掉,执行完毕,到310.T为B,执行第8行程序,访问结点B的右孩子,执行第4行程序判断B的右孩子不为空,进入T为E的611.T为E,执行第6行程序,访问结点E的左孩子,执行第4行程序E判断的左孩子为空,return掉,到10,T为E,执行第7行程序,打印E,进入T为E的812.T为E,执行第8行程序,访问结点E的右孩子,执行第4行程序判断E的右孩子为空,return掉,执行完毕,到10,执行完毕,到2,进入T为A的8...
3.后序遍历
若二叉树为空,则空操作返回;否则
- 先叶子后结点的方式遍历访问左子树
- 先叶子后结点的方式遍历访问右子树
- 访问根结点
(1)例如(左结点-右结点-双亲)
后序遍历的顺序为:GHDBIECFA
(2)以下面的二叉树T为例分析代码:
1 /* 后序递归遍历T */ 2 void PostOrderTraverse(BiTree T) 3 { 4 if(T==NULL) 5 return; 6 PostOrderTraverse(T->lchild); /* 先后序遍历左子树 */ 7 PostOrderTraverse(T->rchild); /* 再后序遍历右子树 */ 8 printf("%c",T->data); /* 显示结点数据,可以更改为其它对结点操作 */ 9 }
最后结果为:KHDEBIFJGCA
1.T为A, 二叉树T根结点不为null,执行第6行程序,进入T为A的62.T为A, 执行第6行程序,访问结点A的左孩子,执行第4行程序判断A的左孩子不为空,进入T为B的63.T为B, 执行第6行程序,访问结点B的左孩子,执行第4行程序判断B的左孩子不为空,进入T为D的64.T为D, 执行第6行程序,访问结点D的左孩子,执行第4行程序判断D的左孩子不为空,进入T为H的65.T为H, 执行第6行程序,访问结点H的左孩子,执行第4行程序判断H的左孩子为空,return掉,到4,进入T为H的76.T为H, 执行第7行程序,访问结点H的右孩子,执行第4行程序判断H的右孩子不为空,进入T为K的67.T为K, 执行第6行程序,访问结点K的左孩子,执行第4行程序判断K的左孩子为空,return掉,到6,进入T为K的78.T为K, 执行第7行程序,访问结点K的右孩子,执行第4行程序判断K的右孩子为空,return掉,到7,T为K,执行第8行程序,打印K,执行完毕,到6,执行完毕,到6,T为H,执行第8行程序,打印H,执行完毕,到4,进入T为D的79.T为D, 执行第7行程序,访问结点D的右孩子,执行第4行程序判断D的右孩子为空,return掉,到9,T为D,执行第8行程序,打印D,执行完毕,到3,进入T为B的710.T为B,执行第7行程序,访问结点B的右孩子,执行第4行程序判断B的右孩子不为空,进入T为E的611.T为E,执行第6行程序,访问结点E的左孩子,执行第4行程序E判断的左孩子为空,return掉,到10,进入T为E的712.T为E,执行第7行程序,访问结点E的右孩子,执行第4行程序判断E的右孩子为空,return掉,到11,执行完毕,到10,T为E,执行第8行程序,打印E,执行完毕,到10,T为B,执行第8行程序,打印B,执行完毕,到1,进入T为A的7...
4.层序遍历
若二叉树为空,则空操作返回;否则
- 先访问根结点
- 从左到右依次访问第i(从根结点下面一层开始)层的每一个结点
- 从左到右依次访问第i+1层的每一个结点
(1)例如
层序遍历的顺序为:ABCDEFGHI
三、二叉树递归遍历算法的Java代码实现(二叉树链式存储结构):
package bigjun.iplab.linkBiTree; import bigjun.iplab.linkQueue.LinkQueue;import bigjun.iplab.linkStack.LinkStack; /** * 二叉树的链式存储结构-二叉链表存储结构 * 前序、中序、后序三种遍历算法的递归实现 */public class LinkBiTree { private BiTreeNode root; // 构造方法1: 构造一棵空树 public LinkBiTree() { this.root = null; } // 构造方法2: 构造一棵非树 public LinkBiTree(BiTreeNode root) { this.root = root; } // 先序递归遍历算法 public void preOrderTraverse(BiTreeNode T) { if (T != null) { System.out.print(T.data); preOrderTraverse(T.lchild); preOrderTraverse(T.rchild); } } // 中序递归遍历算法 public void inOrderTraverse(BiTreeNode T) { if (T != null) { inOrderTraverse(T.lchild); System.out.print(T.data); inOrderTraverse(T.rchild); } } // 后序递归遍历算法 public void postOrderTraverse(BiTreeNode T) { if (T != null) { postOrderTraverse(T.lchild); postOrderTraverse(T.rchild); System.out.print(T.data); } } // 采用构造方法来构造二叉树 public LinkBiTree createLinkBiTree() { BiTreeNode k = new BiTreeNode('K'); // 要先定义孩子,因为程序是按先后顺序执行的 BiTreeNode i = new BiTreeNode('I'); BiTreeNode j = new BiTreeNode('J'); BiTreeNode e = new BiTreeNode('E'); BiTreeNode h = new BiTreeNode('H', null, k); BiTreeNode f = new BiTreeNode('F', i, null); BiTreeNode g = new BiTreeNode('G', null, j); BiTreeNode d = new BiTreeNode('D', h, null); BiTreeNode c = new BiTreeNode('C', f, g); BiTreeNode b = new BiTreeNode('B', d, e); BiTreeNode a = new BiTreeNode('A', b, c); return new LinkBiTree(a); } public static void main(String[] args) throws Exception { LinkBiTree linkBiTree = new LinkBiTree(); // 创建一棵空树 LinkBiTree biTree = linkBiTree.createLinkBiTree(); // 调用创造方法创造根结点为a的二叉树 BiTreeNode root = biTree.root; // 取得二叉树的根结点 System.out.print("先序递归遍历算法得到的序列为: "); linkBiTree.preOrderTraverse(root); System.out.println(); System.out.print("中序递归遍历算法得到的序列为: "); linkBiTree.inOrderTraverse(root); System.out.println(); System.out.print("后序递归遍历算法得到的序列为: "); linkBiTree.postOrderTraverse(root); System.out.println(); } }
- 输出:
先序递归遍历算法得到的序列为: ABDHKECFIGJ 中序递归遍历算法得到的序列为: HKDBEAIFCGJ 后序递归遍历算法得到的序列为: KHDEBIFJGCA
转载于:https://www.cnblogs.com/BigJunOba/p/9209591.html
数据结构(二十)二叉树的递归遍历算法相关推荐
- 数据结构——二叉树的递归遍历算法与非递归遍历算法+层次遍历算法
(文章篇幅有点长,二叉树的递归遍历算法不作详细分析,但是二叉树的非递归遍历算法和层次遍历算法都有非常详细的分析过程,记得往下翻哦!) 二叉树的递归遍历算法实现 我们首先用递归的方法先序遍历创建这样一棵 ...
- 二叉树的递归遍历算法c语言 数据结构,递归创建二叉树c语言实现+详细解释
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 void CreatBiTree(BiTree T) { char a; scanf("%c",&a); if(a=='@') ...
- 树:二叉树的非递归遍历算法
二叉树的递归遍历 二叉树的递归遍历算法,写法很简单,比如说前序遍历树,如下: //前序遍历 void PreOrderTraverse(BiTree tree) {if (NULL != tree){ ...
- C语言-数据结构-二叉树的递归遍历和非递归遍历
看了大量网络相关的理论和程序,多数的C++ 写的,这里使用devC++ 编程语言 C语言; 整合王道考研答案和理论, 还有小甲鱼的数据结构, 郝斌的数据结构,各有特点吧 最值得研究的还是后序遍历的非递 ...
- 实现二叉树的三种非递归遍历算法
[问题描述] 编写程序,实现二叉树的三种非递归遍历算法:先序非递归,中序非递归,后序非递归. [输入形式] 输入建树序列. [输出形式] 输出三种遍历序列. [样例输入] A B C # # # # ...
- 二叉树创建及遍历算法(递归及非递归)(转)
//二叉树处理头文件 //包括二叉树的结构定义,二叉树的创建,遍历算法(递归及非递归), /* 作者:成晓旭 时间:2001年10月7日(18:49:38-20:00:00) 内容:完成二叉树创建,二 ...
- java版 二叉树 所有递归和非递归遍历算法
[java] 通过数组构造二叉树,所有遍历算法以及求二叉树深度的递归算法 [java] import java.util.LinkedList; public class BinaryTree { ...
- 二叉树的递归遍历及非递归遍历
二叉树的基本操作--创建.输出.查找.删除_yyy_zxc的博客-CSDN博客_二叉树的创建与输出创建二叉树过程:/*-----------第一轮循环:ch = A;p->data保存结点值b= ...
- java 二叉树 红黑树_常见数据结构(二)-树(二叉树,红黑树,B树)
常见数据结构(二)-树(二叉树,红黑树,B树) 标签: algorithms [TOC] 本文介绍数据结构中几种常见的树:二分查找树,2-3树,红黑树,B树 写在前面 本文所有图片均截图自course ...
最新文章
- 【转】提示框第三方库之MBProgressHUD iOS toast效果 动态提示框效果
- Bootstrap 与 Jquery validate 结合使用——简单实现
- 获得无向图连通子图_讲透学烂二叉树(一):图的概念和定义—各种属性特征浅析...
- VTK:vtkClipClosedSurface用法实战
- 最优化方法系列:SGD、Adam
- JavascriptHelp
- 路由的Modem信号控制
- windows下SBT的安装与使用
- angular文件上传php,Angular2里获取(input file)上传文件的内容的方法
- gatling系列教程(翻译)-第三节(快速开始)
- Python3----- assert(断言)
- AIX下使用xmanager
- 阵列信号处理学习小结
- Mac Windows fliqlo 时钟屏保
- 然而大部分工程师的期权并没有什么用
- 2021年中式面点师(中级)报名考试及中式面点师(中级)考试总结
- Dism解决win 10访问服务器共享问题,共享需要过时的SMB1协议,安装时错误代码:0x800736B3
- matlab如何进行批量计算,什么是matlab中逐列相关的快速计算方法
- c语言怎么做翻译软件,使用有道翻译API做翻译(c语言实现)
- 使用StreamTorrent观看流媒体电视
热门文章
- 完整安卓项目开发过程和一些细节问题
- webpack打包教程
- 语言中能产生汉明窗吗_0—6岁幼儿的语言、秩序、情感、数学敏感期,有这些特点和表现...
- 项目背景怎么描述_培训回顾 |第六届“互联网+”之创业大赛项目计划书撰写
- 大数据分析机器学习(二)之直方图和多元线性回归
- double类型最大值_2020重新出发,JAVA入门,数据类型
- anaconda版本选择_Python环境搭建之Anaconda快速学习
- YUV格式学习:YUV422P、YV16、NV16、NV61格式转换成RGB24
- mysql用的sql标准_标准SQL语言的用法_MySQL
- dpkg命令_Linux常用命令大全(二)