1. 题目

2. 解答

2.1. 递归法

定义一个存放树中数据的向量 data,从根节点开始,如果节点不为空,那么

    1. 递归得到其左子树的数据向量 temp,将 temp 合并到 data 中去
    1. 递归得到其右子树的数据向量 temp,将 temp 合并到 data 中去
    1. 将当前节点的数值加入到 data 中
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) { vector<int> data = {};
vector<int> temp = {}; if (root != NULL)
{
temp = postorderTraversal(root->left);
data.insert(data.end(),temp.begin(),temp.end());
temp = postorderTraversal(root->right);
data.insert(data.end(),temp.begin(),temp.end());
data.push_back(root->val);
} return data;
}
};
2.2. 迭代法一

仿照前序遍历的思想,只不过这次我们的顺序为中-右-左,然后倒序将其加入到向量中,即为后序左-右-中的结果。

定义一个存放树中节点的栈 node_stack 和存放数据的向量 data,从根节点开始,如果节点不为空或者栈非空,循环以下过程:

    1. 如果节点非空,将节点的值加入 data 的头部,如果节点有左孩子,将节点左孩子压入栈,节点指向其右孩子,循环直到节点为空
    1. 如果节点为空,栈非空,则弹出栈顶节点
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) { // 按照中右左前序遍历,倒序存储即为左右中
vector<int> data = {};
stack<TreeNode*> node_stack;
TreeNode* temp = root; while (temp || !node_stack.empty())
{
while(temp != NULL)
{
data.insert(data.begin(), temp->val); // 在头部插入
if (temp->left) node_stack.push(temp->left);
temp = temp->right;
} // 若最后一个节点没有左子节点,栈为空
if (!node_stack.empty()) // 栈非空
{
temp = node_stack.top();
node_stack.pop();
}
} return data;
}
};
2.3. 迭代法二

后序遍历的话只有某一节点的左右子节点都被访问过之后才能访问该节点。

定义一个存放树中节点的栈 node_stack 和存放数据的向量 data,如果树非空,先将根节点压入栈。

cur 指向当前节点,pre 指向上一次访问的节点,初始化为空,然后栈非空则循环以下过程:

当前节点为栈顶节点

    1. 如果节点左右子节点都为空或者上一次访问的节点为其左右子节点中的一个,(某些节点可能只有一个子节点,所以 pre 不能为空,然后若只有左子节点,则上一次访问的为其左子节点;若有左右子节点,按照压栈顺序,则上一次访问的为其右子节点;)则弹出栈顶节点,将节点数据加入 data,将上一次访问的节点指向当前节点
    1. 否则,如果存在左右子节点,先压入其右子节点,再压入其左子节点
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) { vector<int> data = {};
stack<TreeNode*> node_stack;
if (root) node_stack.push(root); // 树非空,先将根节点压入栈 TreeNode* cur = root; // 当前节点
TreeNode* last = NULL; // 上一次访问的节点 while (!node_stack.empty())
{
cur = node_stack.top(); if ((cur->left == NULL && cur->right == NULL) ||
(last != NULL && (cur->left == last || cur->right == last)))
{
data.push_back(cur->val);
node_stack.pop();
last = cur;
}
else
{
if (cur->right) node_stack.push(cur->right);
if (cur->left) node_stack.push(cur->left);
}
} return data;
}
};

参考资料

获取更多精彩,请关注「seniusen」!

LeetCode 145 ——二叉树的后序遍历的更多相关文章

  1. LeetCode 145. 二叉树的后序遍历(Binary Tree Postorder Traversal)

    145. 二叉树的后序遍历 145. Binary Tree Postorder Traversal 题目描述 给定一个二叉树,返回它的 后序 遍历. LeetCode145. Binary Tree ...

  2. Java实现 LeetCode 145 二叉树的后序遍历

    145. 二叉树的后序遍历 给定一个二叉树,返回它的 后序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [3,2,1] 进阶: 递归算法很简单,你可以通过迭代算法完成 ...

  3. LeetCode 145 二叉树的后序遍历(非递归)

    题目: 给定一个二叉树,返回它的 后序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [3,2,1] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 解题思路: 1 ...

  4. 【leetcode 145. 二叉树的后序遍历】解题报告

    前往二叉树的:前序,中序,后序 遍历算法 方法一:递归 vector<int> res; vector<int> postorderTraversal(TreeNode* ro ...

  5. Leetcode 145. 二叉树的后序遍历

    题目链接 https://leetcode-cn.com/problems/binary-tree-postorder-traversal/description/ 题目描述 给定一个二叉树,返回它的 ...

  6. LeetCode 145. 二叉树的后序遍历(Binary Tree Postorder Traversal)

    题目描述 给定一个二叉树,返回它的 后序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [3,2,1] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 解题思路 后 ...

  7. LeetCode 145. 二叉树的后序遍历 (用栈实现后序遍历二叉树的非递归算法)

    题目链接:https://leetcode-cn.com/problems/binary-tree-postorder-traversal/ 给定一个二叉树,返回它的 后序 遍历. 示例: 输入: [ ...

  8. LeetCode:二叉树的后序遍历【145】

    LeetCode:二叉树的后序遍历[145] 题目描述 给定一个二叉树,返回它的 后序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [3,2,1] 进阶: 递归算法很 ...

  9. 【LeetCode】145. 二叉树的后序遍历

    145. 二叉树的后序遍历 知识点:二叉树:递归:Morris遍历 题目描述 给定一个二叉树的根节点 root ,返回它的 后序 遍历. 示例 输入: [1,null,2,3] 1 \ 2 / 3 输 ...

随机推荐

  1. Unity 游戏框架搭建 (十六) v0.0.1 架构调整

    背景: 前段时间用Xamarin.OSX开发一些工具,遇到了两个问题. QFramework的大部分的类耦合了Unity的API,这样导致不能在其他CLR平台使用QFramework. QFramew ...

  2. 具有代码执行潜力的Vimeo SSRF

    最近我在Vimeo上发现了一个半响应的SSRF代码执行的可能性.这篇博客文章解释了我是如何找到并利用它的. 背景 Vimeo为其API提供了一个名为API Playground的API控制台,使用此W ...

  3. wait();notify();简单例子

    public class Test1{ /** * @param args */ public static void main(String[] args) { new Thread(new Thr ...

  4. Redis(五):Redis的持久化

    Redis的持久化目录导航: 总体介绍 RDB(Redis DataBase) AOF(Append Only File) 总结(Which one) 总体介绍 官网介绍 RDB(Redis Data ...

  5. [Java]Java 9运行Spring Boot项目报错的解决办法

    简介 为了学习和尽快掌握 Java 9 的模块化(Module System)新特性,最近安装了 JDK 9,新建了一个 Spring Boot 进行尝试, 过程中遇到了一下报错问题,写下此文谨作为个 ...

  6. yii学习笔记(5),视图操作

    在控制器调用$this->render()方法来输出视图 function actionLogin(){ $name = "admin"; // 加载视图 return $t ...

  7. JPMML解析PMML模型并导入数据进行分析生成结果

    JPMML解析Random Forest模型并使用其预测分析 导入Jar包 maven 的pom.xml文件中添加jpmml的依赖 <dependency> <groupId> ...

  8. python 两个面试题

    1.下面程序的运算结果是什么?? class Parent: def func(self): print("In Parent func") def __init__(self): ...

  9. java instanceof 的理解

    简单来说,java 中的instanceof 运算符是用来在运行时指出对象是否是特定类的一个实例.instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例. 用法 ...

  10. HyperLedger Fabric 1.4 问题汇总(16)

    16.1 在运行e2e_cli例子时,执行./network_setup.sh up,出现错误:网络搭建之network e2ecli_default not found 问题原因: End-2-En ...