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. HTML的块状、内联、内联块状元素的特点

    元素分类及特点: 1.块级元素: 在html中<div>. <p>.<h1>.<form>.<ul> 和 <li>就是块级元素. ...

  2. 能成为一名合格的Java架构师

    原文地址:http://www.dalbll.com/Group/Topic/ArchitecturedDesign/4943 俗话说“没有见过好程序,怎么可能写出好程序”,同样,也可以说“不了解架构 ...

  3. Docker镜像浅谈

    先抛出几个我在学习过程中产生的几个问题. 1. 容器镜像是什么, 和装系统时的镜像有什么关系? 2. 容器镜像的作用是什么? 3. 不同版本的ubuntu镜像有什么区别, 比如说 ubuntu:18. ...

  4. git获取步骤

    $ git init $ git config --global user.name "[name]" $ git config --global user.email [emai ...

  5. QP之QK原理

    QK是一个很小的抢占式微内核调度程序,它专用用QP中. QK的思想源于SST,Miro Samek重写了自己前期编的SST(Super Simple Task)代码. QK循环查询AO队列的状态表QK ...

  6. 『Python题库 - 简答题』 Python中的基本概念 (121道)

    ## 『Python题库 - 简答题』 Python中的基本概念 1. Python和Java.PHP.C.C#.C++等其他语言的对比? 2. 简述解释型和编译型编程语言? 3. 代码中要修改不可变 ...

  7. 1010 一元多项式求导 (25 分) C语言

    设计函数求一元多项式的导数.(注:x​n​​(n为整数)的一阶导数为nx​n−1​​.) 输入格式: 以指数递降方式输入多项式非零项系数和指数(绝对值均为不超过 1000 的整数).数字间以空格分隔. ...

  8. 解决sublime 的 package control 问题here are no packages available for installation

    参考https://blog.csdn.net/zknxx/article/details/52685094 关于 channel_v3.json 文件 ,下载的压缩包里没有, 需要下载https:/ ...

  9. python 感叹号的作用

    1.     !表示反转逻辑表达式的值 2.      打印格式控制中: x!r代表repr(x),x!s代表str(x),x!a代表ascii(x)

  10. ACM数论-欧几里得与拓展欧几里得

    ACM数论——欧几里得与拓展欧几里得 欧几里得算法: 欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数. 基本算法:设a=qb+r,其中a,b,q,r都是整数,则gcd(a,b)=gcd ...