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. Python 学习笔记(十)Python集合(一)

    回顾 int/float/str/list/tuple/dict 整数型和浮点型是不可变的,不是序列 字符串是不可变的,是序列 列表是可变的,是序列 元组是不可变的,是序列 字典是可变得,但不是序列 ...

  2. 四种常见的 POST 提交数据方式对应的content-type

    原文地址:https://www.cnblogs.com/wushifeng/p/6707248.html application/x-www-form-urlencoded 这应该是最常见的 POS ...

  3. 12种开源Web安全扫描程序

    转自:https://blog.csdn.net/wh211212/article/details/78620963 赛门铁克的一个有趣的报告显示,76%的被扫描网站有恶意软件 如果您使用的是Word ...

  4. 协作开发中常用的Git命令小结

    先提一下最基础的git命令用法: git clone   从远端克隆到本地仓库 git add . (注意add和. 之间有一个空格)将全部改动添加到暂存区 git checkout xxx 撤销更改 ...

  5. Spring Boot 微信-验证服务器有效性【转】

    转:https://blog.csdn.net/jeikerxiao/article/details/68064145 概述 接入微信公众平台开发,开发者需要按照如下步骤完成: 在自己服务器上,开发验 ...

  6. ssh登录等待时间超时问题的解决

    最近使用ssh登录服务器时,发现许多服务器会报告等待时间超时的错误,通过网上查找发现是由于ssh中的配置中开启了DNS反查的功能,导致在反查过程中消耗了很长的时间,现将解决方法总结如下: 使用root ...

  7. 04.nginx使用

    博客为日常工作学习积累总结: 1.安装依赖包 安装pcre :yum install pcre pcre-devel -y        安装openssl:yum install openssl o ...

  8. Windows 安装 MongoDB 并开启认证

    下载 可以自行上官网找需要的版本,Windows系统各个64位版本下载地址: http://dl.mongodb.org/dl/win32/x86_64 安装 正常的软件安装流程,这里就不细讲了. 配 ...

  9. HTML+css3 图片放大效果

    <div class="enlarge"> <img src="xx" alt="图片"/> </div> ...

  10. springboot+layui实现增删查改

    本文描述springboot和layui的结合,采用了springboot内置的jdbc,根据不同需要可以进行修改:分页采用了layui中自带分页格式! ----------------------- ...