必须掌握,二叉树的前中后序遍历(迭代+递归)详细代码
对于二叉树的三种遍历方式,无论是简单的递归写法,还是迭代写法,都是在面试中容易被考到的,所以这篇文章就把这个常考知识点给解释清楚。
1.二叉树的前序遍历(LeetCode 144题)
前序遍历的关键在于:先遍历根节点,再遍历左子树,再遍历右子树。
即:根→左→右
(1) 递归写法
对于递归写法大家肯定都是非常清楚的,因为它的代码很简单,也比较容易理解,如下:
class Solution {List<Integer> res = new ArrayList<>();public List<Integer> preorderTraversal(TreeNode root) {if(root == null) return res;dfs(root);return res;}public void dfs(TreeNode root){if(root == null) return ;res.add(root.val); //先遍历根节点dfs(root.left); //再遍历左子树dfs(root.right); //再遍历右子树}
}
(2) 迭代写法
要把递归写法改成迭代写法,需要用到的一个很重要的数据结构:栈,用它来保存我们上一个结点,也就是记录我们从哪里来,这样在处理完某个结点的时候,我们可以通过栈来倒退回上一步,这就是迭代写法的核心。
代码如下:
class Solution {public List<Integer> preorderTraversal(TreeNode root) {List<Integer> res = new ArrayList<>();Stack<TreeNode> stk = new Stack<>();if(root == null) return res;while(root != null || !stk.isEmpty()){while(root != null){res.add(root.val); //遍历根节点stk.push(root); //把根节点加入栈中保证我们可以退回到上一步root = root.left; //遍历左子树}root = stk.pop(); //出循环时root为null,回到上一步(即栈顶元素)root = root.right; //遍历它的右子树}return res;}
}
2.二叉树的中序遍历(LeetCode 94题)
中序遍历的关键在于:先遍历左子树,再遍历根节点,最后遍历右子树。
即:左→根→右。
(1) 递归写法
class Solution {List<Integer> res = new ArrayList<>();public List<Integer> inorderTraversal(TreeNode root) {if(root == null) return res;dfs(root);return res;}public void dfs(TreeNode root){if(root == null) return ;dfs(root.left); //遍历左子树res.add(root.val); //遍历根节点dfs(root.right); //遍历右子树}
}
(2) 迭代写法
同样的道理用栈来记录我们的遍历路径,代码与前序遍历十分相似。
class Solution {public List<Integer> inorderTraversal(TreeNode root) {List<Integer> res = new ArrayList<>();Stack<TreeNode> stk = new Stack<>();if(root == null) return res;while(root != null || !stk.isEmpty()){while(root != null){stk.push(root); //记录遍历路径root = root.left; //遍历左子树}root = stk.pop(); //出循环时root为null,回到上一步(即栈顶)res.add(root.val); //遍历根节点root = root.right; //遍历右子树}return res;}
}
对比前序遍历可以发现,其实就是res.add(root.val)
这一行代码的位置发生了变化,所以是比较好记忆的。
3.二叉树的后序遍历(LeetCode 145题)
后序遍历的关键在于:先遍历左子树,再遍历右子树,最后遍历根节点。
即:左→右→根。
(1) 递归写法
class Solution {List<Integer> res = new ArrayList<>();public List<Integer> postorderTraversal(TreeNode root) {if(root == null) return res;dfs(root);return res;}public void dfs(TreeNode root){if(root == null) return ;dfs(root.left); //遍历左子树dfs(root.right); //遍历右子树res.add(root.val); //遍历根节点}
}
(2) 迭代写法
后序遍历的迭代写法稍微有一点不同,需要转换一下思路,如果我们直接去写的话会发现并不好写,所以我们可以观察一下特点,前序遍历的顺序是:根左右,后序遍历的顺序是:左右根,如果把前序遍历的结果反转一下就是:右左根,和后序遍历的顺序差在左右子树的遍历顺序上,所以后序遍历的迭代写法可以在前序遍历的迭代写法上进行小小的修改。
即:先遍历根节点,再遍历右子树,最后遍历左子树。得到的结果最后反转一下,就是二叉树的后序遍历。
class Solution {public List<Integer> postorderTraversal(TreeNode root) {List<Integer> res = new ArrayList<>();Stack<TreeNode> stk = new Stack<>();if(root == null) return res;while(root != null ||!stk.isEmpty()){while(root != null){res.add(root.val); //遍历根节点stk.push(root); //记录遍历路径root = root.right; //遍历右子树}root = stk.pop(); //出循环时root为null,回到上一步(即栈顶)root = root.left; //遍历左子树}Collections.reverse(res); //反转结果return res;}
}
总结
我们可以发现,其实二叉树的前中后序遍历的迭代写法是非常相似的,我们只需要理解之后就十分容易直接记住。
前序遍历与中序遍历代码的区别只是一行代码的位置发生了改变;
后序遍历是在前序遍历的基础上稍作修改;
所以我们只需要记住三点:
(1) 迭代写法需要用到栈
(2) 循环是while(root != null || !stk.isEmpty())
(3) 前序遍历思路,中序遍历改一行代码位置,后序遍历:根右左最后把答案反转
二叉树的遍历就是这么简单~
必须掌握,二叉树的前中后序遍历(迭代+递归)详细代码相关推荐
- 二叉树的前,中,后序遍历(思路分析) [Java][数据结构]
二叉树的前,中,后序遍历(思路分析) 前序遍历: 先输出父节点, 再遍历左子树和右子树 中序遍历: 先遍历左子树, 再输出父节点,再遍历右子树 后序遍历: 先遍历左子树,再遍历右子树,最后输出父节点 ...
- Java二叉树的前中后序遍历
Java二叉树的前中后序遍历 1.前序遍历 1.1前序遍历概念 1.2前序遍历习题 2.中序遍历 2.1中序遍历概念 2.2中序遍历习题 3.后续遍历 3.1后序遍历概念 3.2后序遍历习题 大家好, ...
- 数据结构之二叉树的前中后序遍历以及层序遍历
学习目标:读完这篇博客搞定二叉树的前中后序以及层序遍历 首先:你应该明白什么是二叉树,下面这幅图就是一个完全二叉树 其实所谓的二叉树就是一个节点有小于等于二个分支的树,可以没有分支,可以有1条分支,可 ...
- 数据结构与算法(java):树-二叉树(二叉查找树(BST)、线索化二叉树、哈夫曼树、平衡二叉树【AVL】、二叉树的前中后序遍历)
二叉树 1.定义 二叉树 就是度不超过2的树(每个结点最多只有两个子结点).如图 2.特殊二叉树 满二叉树 当二叉树的每一个层的结点树都达到最大值,则这个二叉树就是满二叉树. 完全二叉树 叶结点只能出 ...
- 二叉树的前中后序遍历之迭代法(非统一风格迭代方式)
文章目录 前言 一.前序遍历(迭代法) 二.中序遍历(迭代法) 三.后序遍历(迭代法) 总结 前言 「递归的实现就是:每一次递归调用都会把函数的局部变量.参数值和返回地址等压入调用栈中」,然后递归返回 ...
- 【Java数据结构】二叉树的前中后序遍历(递归和非递归)
二叉树的遍历 递归做法 前序遍历 中序遍历 后序遍历 非递归 前序遍历 中序遍历 后序遍历 二叉树遍历是二叉树的一种重要操作 必须要掌握 二叉树的遍历可以用递归和非递归两种做法来实现 递归做法 前序遍 ...
- 二叉树的前中后序遍历(考试常考)
二叉树遍历的概念 二叉树的遍历是按某种规则对二叉树的每个节点均只被访问一次,根据根节点访问位置的不同分为三种:先序遍历(根左右).中序遍历(左根右).后序遍历(左右根). 由于树是通过 ...
- 【数据结构】二叉树的前中后序遍历
二叉树的三种遍历 1. 创建一棵简单的二叉树 1.1 二叉树结构体实现 1.2 创造一个二叉树结点的函数 1.3 手动创造一棵二叉树 2.为什么要遍历? 3.最重要的知识:由二叉树引出的子问题分析 4 ...
- 二叉树(C++):创建,前中后序遍历(递归+非递归),获取叶子节点个数,获取树的高度
文章目录 前言 创建二叉树 先序遍历 中序遍历 后序遍历 获取叶子节点个数 获取树的高度 测试代码 前言 现有如下二叉树: 关于二叉树的相关操作,我们能够发现二叉树从根节点到子节点,以及每个中间节点基 ...
- 二叉树的前中后序遍历之迭代法(统一风格迭代方式)
一.前序遍历(迭代法)->右左中 前序遍历是中左右,每次先处理的是中间节点,那么先将根节点放入栈中,然后将右孩子加入栈,再加入左孩子. 为什么要先加入 右孩子,再加入左孩子呢?因为这样出栈的时候 ...
最新文章
- APK 签名中应该注意的一些点 (未完待续)
- 多数据源:spring boot+mybatisplus配置
- proto的介绍和基础使用
- 旅行线路定制主题响应式手机模板
- 如何找mysql8.0的rpm安装包_centos7 mysql8.0 RPM软件包方式安装
- 从四大造字法看文字所承载的文化_对央视“汉字的魅力”讲授之管见(《天津教育报》2012年6月15日)...
- 在ubuntu中使用cv2.imshow()报错 No protocol specified qt.qpa.xcb: could not connect to display :0
- php为首字母的词语,PHP提取中英文词语及数字首字母的简单示例
- 少年Vince之遐想
- 版mysql客户端工具_【小白福利—初级DBA入门必看】MySQL常用工具介绍(三)——客户端工具MySQL...
- CentOS 7 x64部署tomcat
- adb 连接手机 cannot connect to xxx.xxx.x.xx:5555: 由于目标计算机积极拒绝,无法连接。 (10061)
- 网络知识之----http七层协议
- 安全的随想网络空间测绘
- 模拟法-鸡兔同笼问题
- 如何用Camtasia将喜欢的视频做出复古的感觉
- mysql引用表无效列_Mysql使用索引可能失效的场景
- 贝叶斯(朴素贝叶斯,正太贝叶斯)及OpenCV源码分析
- STM32通信:IIC (二)
- 如何在xp系统中安装python(安装anachonda)