前序遍历 (preorder traversal) - 中序遍历 (inorder traversal) - 后序遍历 (postorder traversal)
前序遍历 (preorder traversal) - 中序遍历 (inorder traversal) - 后序遍历 (postorder traversal)
1. 前序遍历 (preorder traversal) - 中序遍历 (inorder traversal) - 后序遍历 (postorder traversal)
- 遍历的递归实现。
- 遍历的非递归实现 - 使用栈的非递归实现。
- 二叉树的深度优先遍历的非递归做法是采用栈,广度优先遍历的非递归做法是采用队列。
- 深度优先对每一个可能的分支路径深入到不能再深入为止,先序遍历、中序遍历、后序遍历属于深度优先遍历。
- 广度优先遍历也称为层次遍历,从上往下,从左往右访问结点,访问完一层就进入下一层,直到没有结点可以访问为止。
typedef struct TREENODE
{struct TREENODE *left;struct TREENODE *right;struct TREENODE *parent;int data;
} TreeNode;
2. Example
2.1 前序遍历 (preorder traversal)
首先访问根结点,然后前序遍历其左子树,最后前序遍历其右子树。
遍历结果:A B D H I E J C F G
2.2 中序遍历 (inorder traversal)
首先中序遍历根结点的左子树,然后访问根结点,最后中序遍历其右子树。
遍历结果:H D I B J E A F C G
2.3 后序遍历 (postorder traversal)
首先后序遍历根结点的左子树,然后后序遍历根结点的右子树,最后访问根结点。
遍历结果:H I D J E B F G C A
3. Example
3.1 中序遍历 (inorder traversal)
首先中序遍历根结点的左子树,然后访问根结点,最后中序遍历其右子树。
遍历结果:B D C A E H G K F
我们从根节点 A 看起,遍历 A 的左子树。
A 的左子树存在,找到 B,此时 B 看做根节点,遍历 B 的左子树。
B 的左子树不存在,返回 B,根据 [左根右]
的遍历规则,记录 B,遍历 B 的右子树。
B 的右子树存在,找到 C,此时 C 看做根节点,遍历 C 的左子树。
C 的左子树存在,找到 D。由于 D 是叶子节点,无左子树,记录 D。D 无右子树,返回 C,根据 [左根右]
的遍历规则,记录 C,遍历 C 的右子树。
C 的右子树不存在,返回 B,B 的右子树遍历完,返回 A。A 的左子树遍历完毕,根据 [左根右]
的遍历规则,记录 A,遍历 A 的右子树。
A 的右子树存在,找到 E,此时 E 看做根节点,遍历 E 的左子树。
E 的左子树不存在,返回 E,根据 [左根右]
的遍历规则,记录 E,遍历 E 的右子树。
E 的右子树存在,找到 F,此时 F 看做根节点,遍历 F 的左子树。
F 的左子树存在,找到 G,此时 G 看做根节点,遍历 G 的左子树。
G 的左子树存在,找到 H,由于 H 是叶子节点,无左子树,记录 H。H 无右子树,返回 G,根据 [左根右]
的遍历规则,记录 G,遍历 G 的右子树。
G 的右子树存在,找到 K,由于 K 是叶子节点,无左子树,记录 K。K 无右子树,返回 G,根据 [左根右]
的遍历规则,记录 F,遍历 F的右子树。
F 的右子树不存在,返回 F,E 的右子树遍历完毕,返回 A。A 的右子树也遍历完毕。
遍历结果:B D C A E H G K F
4. Example
4.1 前序遍历 (preorder traversal)
首先访问根结点,然后前序遍历其左子树,最后前序遍历其右子树。
遍历结果:A B D E G H C F
4.2 中序遍历 (inorder traversal)
首先中序遍历根结点的左子树,然后访问根结点,最后中序遍历其右子树。
遍历结果:D B G E H A C F
4.3 后序遍历 (postorder traversal)
首先后序遍历根结点的左子树,然后后序遍历根结点的右子树,最后访问根结点。
遍历结果:D G H E B F C A
4.4 层序遍历 (breadth-first traversal)
遍历结果:A B C D E F G H
前序、中序、后序是针对根节点而言的,左右子树的遍历顺序不变。前序就是根节点最先遍历,然后左右子树。中序就是根节点放在中间遍历。后序就是把根节点放在最后遍历。
5. 前序遍历 (preorder traversal)
二叉树的深度优先遍历的非递归做法是采用栈 (stack)。
首先访问根结点,然后前序遍历其左子树,最后前序遍历其右子树。
5.1 Example
- 设置一个栈,将根节点 push 到栈中。
- 循环检测栈是否为空,若不空,则取出栈顶元素,保存其值。
- 查看栈顶元素右子节点是否存在,若存在则 push 到栈中。查看栈顶元素左子节点,若存在,则 push 到栈中。
- 继续回到 2. 执行,直到栈空。
5.2 Example
- 设置一个栈,将根节点 push 到栈中 (
push(root)
)。 node = pop(), list.add(node.val)
push(node.right)
push(node.left)
- 循环步骤
3.
直到栈空。
6. 中序遍历 (inorder traversal)
二叉树的深度优先遍历的非递归做法是采用栈 (stack)。
首先中序遍历根结点的左子树,然后访问根结点,最后中序遍历其右子树。
- 设置一个栈。
- 将根节点 root,以及 root 的持续左孩子都压入栈中。
node = pop(), list.add(node.val)
root = node.right
- 循环步骤
2.
直到栈为空且root
为NULL
。
7. 后序遍历 (postorder traversal)
二叉树的深度优先遍历的非递归做法是采用栈 (stack)。
首先后序遍历根结点的左子树,然后后序遍历根结点的右子树,最后访问根结点。
- 设置一个栈,将根节点 push 到栈中 (
push(root)
)。 node = pop()
list.add(0 , node.val)
push(node.left)
push(node.right)
- 循环步骤
2.
直到栈空。
前序遍历 (preorder traversal) - 中序遍历 (inorder traversal) - 后序遍历 (postorder traversal)相关推荐
- 由序列确定二叉树:前序序列和中序序列构造二叉树 后序序列和中序序列构造二叉树 层次遍历序列和中序遍历序列构造二叉树 代码实现(c语言)
下面三种序列可以唯一的构造唯一的一棵二叉树: 前序序列和中序序列构造二叉树 后序序列和中序序列构造二叉树 层次遍历序列和中序遍历序列构造二叉树 #include<stdio.h> #inc ...
- PAT甲级1020变体:已知二叉树层序+中序序列,求后序遍历序列
PAT甲级1020变体:已知二叉树层序+中序序列,求后序遍历序列 题目 输入格式 输出格式 输入样例 输出样例 代码 题目 已知二叉树层序+中序序列,求后序遍历序列. 输入格式 第一行给出该二叉树的节 ...
- 已知满二叉树先序序列如何求后序序列
如题 自用笔记 如有错误欢迎及时指正 面对仅仅知道先序序列(DLR)求后序序列(LRD),首先想到的是不可能,若对一般的二叉树而言确实无法做到,但是满二叉树的特殊性使得该命题成立!下面给出本文所用例子 ...
- 【算法系列之线索化二叉树,前序线索化、中序线索化、后序线索化以及遍历~】
1.何谓线索化二叉树 2.线索化二叉树的本质 3.线索化二叉树的存储结构 4.构建线索化二叉树 4.1.先序线索化 4.2.中序线索化 4.3.后序线索化 5.遍历线索化二叉树 5.1.先序遍历 先序 ...
- C/C++面试题—重建二叉树【前序 + 中序- 重建二叉树 和 后序 + 中序 - 重建二叉树】
题目介绍 题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字. 例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{ ...
- 后序遍历c语言程序,C++对树进行后序遍历的代码
下面是编程之家 jb51.cc 通过网络收集整理的代码片段. 编程之家小编现在分享给大家,也给大家做个参考. #include #include struct Node{ Node *lchild;/ ...
- Uva536 Tree Recovery二叉树重建(先序和中序确定二叉树,后序输出)
题目大意:给定二叉树先序和中序遍历,输出二叉树后序遍历. 方法:将英文字母映射为数字,利用数组存储,先序第一个节点是父节点,然后再从中序遍历中找到位置.注意边界.代码也很简单一次ac. #includ ...
- 已知二叉树先序序列和中序序列,求后序序列
回答了百度知道上的一个提问,原题是这样的: 当一棵二叉树前序序列和中序序列分别为HGEDBFCA和EGBDHFAC时,其后序序列为什么?当一棵二叉树前序序列和中序序列分别为HGEDBFCA和EGBDH ...
- 二叉树的先序线索化、中序线索化、后序线索化的对比
有一点需要注意:在先序遍历一个节点的左子树时,需要判断其ltag的值是否为0,如果为0可以正常遍历,但是,如果为1就不能进行遍历.因为ltag的值为1说明该结点的左指针指向的是它的前驱结点而不是左孩子 ...
- 中序线索树和后序线索树
约定 Node* Bool Data Bool Node* lchild LTag data RTag rchild LTag=0 时lchild指向左儿子: LTag=1 时lchild指向前驱: ...
最新文章
- python语言怎么学-如何从零开始学习Python,python语言编程入门
- windows 常用系统变量
- WPF4文字模糊不清晰、边框线条粗细不一致的解决方法
- android SDK安装以及环境变量配置
- 汇编语言 王爽 第四版 课后检测点 课后实验 包括解释 持续更新~~
- matlab学习网站
- 《善用佳软:高效能人士的软件应用之道》一2.6 小工具之计算器
- 台式电脑连接电脑主机与显示器
- 《Nature》《Science》封面发表的AI相关文章
- BIOS设置中的启动引导模式以及SATA的三种模式
- k8s(十三)、企业级docker仓库Harbor在kubernetes上搭建使用
- paip 破解网站手机验证码
- 9 使用AD滴泪与敷铜
- 常用的3种高效睡眠法,因人而异
- jquery canvas网页画布画图
- 2022-2028年中国移动电商行业深度调研及投资前景预测报告
- matlab离散点数字微分,MATLAB数值积分与微分
- 搜索:Flood Fill
- 1G2G3G4G5G:一部波澜壮阔的移动通信史
- 计算机体系结构——动态流水线动态调度详解