145. 二叉树的后序遍历

知识点:二叉树;递归;Morris遍历

题目描述

给定一个二叉树的根节点 root ,返回它的 后序 遍历。

示例

输入: [1,null,2,3]
1
\
2
/
3 输出: [3,2,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> list = new ArrayList<>();
public List<Integer> postorderTraversal(TreeNode root) {
if(root == null) return list;
postorderTraversal(root.left);
postorderTraversal(root.right);
list.add(root.val);
return list;
}
}

时间复杂度:0(N),每个节点恰好被遍历一次;

空间复杂度:O(N),递归过程中栈的开销;

解法二:迭代法

后序遍历可以用前序遍历来解决,想一下前序遍历:根左右,我们先压右树再压左树。怎么实现根右左呢,可以先压左树再压右树嘛,然后反过来不就是左右根了吗?(反过来用栈来实现,栈一个很大的作用就是实现逆序)

/**
* 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> list = new ArrayList<>();
public List<Integer> postorderTraversal(TreeNode root) {
Stack<TreeNode> stackA = new Stack<>();
Stack<TreeNode> stackB = new Stack<>();
if(root == null) return list;
stackA.push(root);
while(!stackA.isEmpty()){
TreeNode top = stackA.pop();
stackB.push(top);
if(top.left != null) stackA.push(top.left);
if(top.right != null) stackA.push(top.right);
}
while(!stackB.isEmpty()){
list.add(stackB.pop().val);
}
return list;
}
}

解法三:Morris遍历

构建从下到上的连接,一条路能够走遍所有节点;

当我们返回上层之后,也就是将连线断开的时候,打印下层的单链表。

/**
* 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> list = new ArrayList<>();
public List<Integer> postorderTraversal(TreeNode root) {
if(root == null) return list;
TreeNode cur = root;
TreeNode mostRightNode = null;
while(cur != null){
mostRightNode = cur.left;
if(mostRightNode != null){
while(mostRightNode.right != null && mostRightNode.right != cur){
mostRightNode = mostRightNode.right;
}
if(mostRightNode.right == null){
mostRightNode.right = cur;
cur = cur.left;
continue;
}else{
mostRightNode.right = null;
postMorrisPrint(cur.left); //第二次到达时打印下一层的单链表;
cur = cur.right;
}
}else{
cur = cur.right;
}
}
postMorrisPrint(root);
return list;
}
private void postMorrisPrint(TreeNode node){
TreeNode reverseList = reverseList(node); //反转单链表;
TreeNode cur = reverseList;
while(cur != null){
list.add(cur.val);
cur = cur.right;
}
reverseList(reverseList);
}
private TreeNode reverseList(TreeNode node){
TreeNode pre = null;
TreeNode cur = node;
while(cur != null){
TreeNode next = cur.right;
cur.right = pre;
pre = cur;
cur = next;
}
return pre;
}
}

体会

后序遍历的特殊在于其Morris遍历;

相关链接

二叉树

最新文章

  1. docker学习之二镜像创建
  2. AppBox升级进行时 - 扁平化的权限设计
  3. servlet的四个作用域
  4. spring容器加载完毕做一件事情(利用ContextRefreshedEvent事件)转
  5. shell-bash学习01基础、打印、环境变量
  6. Java设计模式-中介者模式(Mediator)
  7. Java Synchronized的用法
  8. spring源码学习之:spring容器的applicationContext启动过程
  9. glibc的了解,对内核的封装
  10. PhpStorm 10.0注册
  11. 浅谈JAVA中“增强”类的某个方法的几个中方法!
  12. 用vue开发一个app(1,基础环境配置)
  13. Java作业八(2017-10-30)
  14. JVM--02
  15. vue学习目录 vue初识 this指向问题 vue组件传值 过滤器 钩子函数 路由 全家桶 脚手架 vuecli element-ui axios bus
  16. Service Worker 离线无法缓存Post请求的问题解决
  17. Parquet格式解析
  18. Android Studio开发学习 - 1. 添加Activity
  19. python核心编程2 第九章 练习
  20. py thon 多线程(转一篇好文章)

热门文章

  1. JUC 并发编程--01,线程,进程,经典卖票案例, juc的写法
  2. 【题解】poj 3254 Corn Fields
  3. 关于 Windows 下 Qt 开发,这个问题必须要搞清楚!
  4. 聊聊 Feign 的实现原理
  5. 小程序动态修改页面标题setNavigationBarTitle
  6. VsCode中代码折叠快捷键
  7. PUN丨实用API
  8. 一台服务器能支撑多少个TCP连接
  9. 37、linux下安装python3.6和django
  10. 堆&amp;&amp;优先队列&amp;&amp;TreeMap