【LeetCode笔记】94 144 145. 二叉树的前序、中序、后序遍历的迭代与递归(Java、dfs、迭代)
文章目录
- 一. 题目描述
- 二. 代码 & 思路
- 1. 递归的写法
- 2. 迭代的写法(本文重点来了)
- 1) 前序
- 2) 中序
- 3) 后序
直接来个整合吧,也方便看。之前只写了递归的,现在补上迭代的(迭代才是考点!)
是面试高频题,要好好掌握好各自间的区分哦!
一. 题目描述
题目描述基本上一样,就只展示中序的题干了
二. 代码 & 思路
1. 递归的写法
- 这里比较简单,就不赘述了,就是换换顺序。
/*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val = val; }* TreeNode(int val, TreeNode left, TreeNode right) {* this.val = val;* this.left = left;* this.right = right;* }* }*/
class Solution {List<Integer> ans = new ArrayList<>();public List<Integer> inorderTraversal(TreeNode root) {mid(ans);return ans;}// 前序void first(TreeNode root){if(root == null){return;}ans.add(root.val);first(root.left);first(root.right);}// 中序void mid(TreeNode now){if(now == null){return;}mid(now.left);ans.add(now.val);mid(now.right);}// 后序void last(TreeNode now){if(now == null){return;}last(now.left);last(now.right);ans.add(now.val);}
}
2. 迭代的写法(本文重点来了)
说实话,三份代码简直模版:while & if else & stack,写的前五行代码是一样的
- 首先明确一点,栈的作用。
- 前面的递归写法,就是 JVM 隐式地帮我们进行了栈的操作
- 迭代:用栈模仿虚拟机的调用过程
- 前序 & 中序很像,后序相对难一点,需要维护一个 pre 结点
1) 前序
class Solution {List<Integer> ans = new ArrayList<>();public List<Integer> preorderTraversal(TreeNode root) {// 迭代:通过栈模拟虚拟机的递归结构Stack<TreeNode> myStack = new Stack<>();TreeNode now = root;// 前中后写的前五行代码都是一样的while(now != null || !myStack.isEmpty()){// 非null情况:先加再说!入栈,然后直接往左走if(now != null){ans.add(now.val);myStack.push(now);now = now.left;}// null情况:那就走父结点的右边!else {now = myStack.pop().right;}}return ans;}
}
2) 中序
- 和前序相比,都是一路向左,到头了就取父结点的右边
- 不同之处在于,ans.add的位置,前序 & 中序分布在 if else 中
class Solution {List<Integer> ans = new ArrayList<>();public List<Integer> inorderTraversal(TreeNode root) {// 迭代:用栈模仿虚拟机的调用过程Stack<TreeNode> myStack = new Stack<>();TreeNode now = root;// 结束条件:当前结点已经走到底,并且栈中也无可用结点了while(now != null || !myStack.isEmpty()){// 非null情况:入栈,一路向左if(now != null){myStack.push(now);now = now.left;}// null情况:左到头了,取出父节点,加入答案,然后从父结点的右结点继续else{TreeNode temp = myStack.pop();ans.add(temp.val);now = temp.right;}}return ans;}
}
3) 后序
- 非null情况处理,和中序完全一样
- 唯一一个使用了peek的,也就是说:null情况不一定会pop
- 代码重点在于:null 情况部分,详细见代码
- pre 的更新是从底向上的(有点抽象,结合代码可能比较好理解)
class Solution {List<Integer> ans = new ArrayList<>();public List<Integer> postorderTraversal(TreeNode root) {Stack<TreeNode> myStack = new Stack<>();TreeNode now = root;// 相对于前序 & 中序,此处加了个 pre 结点,用来验证右边结点是否走过TreeNode pre = null;while(now != null || !myStack.isEmpty()){// 非null情况:先 push 当前结点,然后往左冲!if(now != null){myStack.push(now);now = now.left;}// null情况:冲到头了else{// 注意这里是 peek,不一定 pop 掉now = myStack.peek();// 取答案的情况:父结点无右结点 Or 父节点的右结点已走过if(now.right == null || now.right == pre){ans.add(now.val);// 更新 pre 值为当前值,表示当前值已走过,供now的父节点使用pre = now;// pop 掉父节点myStack.pop();// 更新 now 为 null,下一次循环继续peeknow = null;}// 可以继续走右边的情况else{now = now.right;}}}return ans;}
}
【LeetCode笔记】94 144 145. 二叉树的前序、中序、后序遍历的迭代与递归(Java、dfs、迭代)相关推荐
- java中二叉树_Java工程师面试1000题224-递归非递归实现二叉树前、中、后序遍历...
224.使用递归和非递归实现二叉树的前.中.后序遍历 使用递归来实现二叉树的前.中.后序遍历比较简单,直接给出代码,我们重点讨论非递归的实现. class Node { public int valu ...
- C++实现二叉树 前、中、后序遍历(递归与非递归)非递归实现过程最简洁版本
本文并非我所写,是复制的该链接中的内容: 最近学习二叉树,想编程实现递归和非递归的实现方式: 递归的方式就不说了,因为大家的递归程序都一样:但是对于非递归的实现方式, 根据这几天的查阅资料已看到差不多 ...
- 【LeetCode | 二叉树前、中、后序遍历{迭代法}实现】
1.前序遍历 // 解题思路:利用栈的原理实现以迭代方法来前序遍历(根左右)二叉树 class Solution { public:vector<int> preorderTraversa ...
- java数据结构学习笔记-二叉树前、中、后序遍历
public class BinaryTreeDemo {public static void main(String args[]){Employee emp1= new Employee(1,&q ...
- 【LeetCode | 二叉树前、中、后序遍历{递归法}实现】
1.前序遍历 #include <iostream> #include <vector> #include <queue> #include <algorit ...
- 二叉树前、中、后序线索化及遍历
public class ThreadedBinaryTree {public static void main(String[] args){Heronodes node1=new Heronode ...
- 用前序中序创建二叉树(用中序后序创建二叉树)
定义二叉树结点 比如就拿这个二叉树 前序中序创建 因为前序遍历的顺序是 根 , 左 ,右. 中序的遍历是 左 根 右. 我们会很不好想,但我们可以用前序和中序把上面那个二叉树的遍历一边 前序遍历:AB ...
- 栈的亚特兰数与二叉树的前序中序遍历序列
栈的亚特兰数与二叉树的前序中序遍历 @(算法学习) 已经熟知的是二叉树的中序遍历和先序遍历可以唯一确定一棵树. 更有趣的知识点是,以先序遍历序列作为入栈序列,那么出栈序列恰为中序遍历.这样就把两种遍历 ...
- 二叉树的深度(前序 中序 后序 递归非递归搜素)、广度、搜索 C++
a b c 使用 1 2 3 表示 /* 描述:二叉树的深度(前序 中序 后序 递归非递归搜素).广度.搜索 作者:jz 日期:20140819 */ #include<stdio.h> ...
最新文章
- RHCSA7-NOTE(红帽管理员-题库详细笔记)
- 洛谷 P1273 【有线电视网】
- html首字母样式,html标签手册
- 解决: IDEA 代码 commit 后,Local Changes 中代码依旧在,提交失败,报错:is out of date
- DDD 领域驱动设计落地实践:六步拆解 DDD
- 大学学python用记笔记吗_3年Python程序员平时学习笔记总结,对于学习Python非常有帮助!...
- 谷歌AI:根据视频生成深度图,效果堪比激光雷达
- WIN7下安装SVNserver端及client搭建协作环境
- python3.3使用tkinter实现猜数字游戏代码
- OSChina 周四乱弹 —— 有这个发现自己并不需要女朋友了
- 如何评估语音质量好坏?
- 软件工程实验二Visio的使用
- android+号码归属地数据库,Android手机号码归属地的查询
- 如何通过芯片手册寻找操作GPIO
- android判断图片是否模糊,Android 图片模糊 性能总结
- CTF PWN-攻防世界XCTF新手区WriteUp
- java freemarker转PDF和Word
- 微信小程序 - 二维码数据解析,如何扫码进入开发版测试二维码数据
- PMP学习笔记20161130
- mmap和shmget的区别
热门文章
- Python 程序 可以一直输入 quit_从零开始学Python - 第002课:第一个Python程序
- 软件测试知识产权保护,一种软件测试方法及软件测试系统专利_专利申请于2017-09-07_专利查询 - 天眼查...
- centos7调节虚拟机字体_初次安装虚拟机中Ubuntu16.04系统设置的一些小问题(小白教程)...
- OpenCV学习笔记(七):形态学morpholgy(1):腐蚀/膨胀:enrode(),dilate()
- VS2013中CUDA的配置
- dataframe常用操作总结
- MySQL索引原理、失效情况
- Python 的协程库 greenlet 和 gevent
- CompletableFuture详解~CompletionStage
- SpringBoot 自带工具类~StreamUtils