题目:

Given a binary tree, return the postorder traversal of its nodes' values.

For example:
Given binary tree {1,#,2,3},

   1
    \
     2
    /
   3

return [3,2,1].

Note: Recursive solution is trivial, could you do it iteratively?

说明:

1) 两种实现,递归与非递归 , 其中非递归有两种方法

2)复杂度分析:时间O(n)、空间O(n)

实现:

一、递归

 /**
  * Definition for binary tree
  * struct TreeNode {
  *     int val;
  *     TreeNode *left;
  *     TreeNode *right;
  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
  * };
  */
 class Solution {
 public:
     vector<int> postorderTraversal(TreeNode *root) {
         vector<int> root_vec;
         vector<int> left_vec;
         vector<int> right_vec;
         if(root==NULL) return root_vec;
         if(root->left) left_vec=postorderTraversal(root->left);
         if(root->right) right_vec=postorderTraversal(root->right);
         root_vec.push_back(root->val);
         left_vec.insert(left_vec.end(),right_vec.begin(),right_vec.end());
         left_vec.insert(left_vec.end(),root_vec.begin(),root_vec.end());
         return left_vec;
     }
 };

二、非递归

根据后序遍历的顺序,先访问左子树,再访问右子树,后访问根节点,而对于每个子树来说,又按照同样的访问顺序进行遍历,后序遍历的非递归的实现相对来说要难一些,要保证根节点在左子树和右子树被访问后才能访问,思路如下:

对于任一节点P,

1)先将节点P入栈;

2)若P不存在左孩子和右孩子,或者P存在左孩子或右孩子,但左右孩子已经被输出,则可以直接输出节点P,并将其出栈,将出栈节点P标记为上一个输出的节点,再将此时的栈顶结点设为当前节点;

3)若不满足2)中的条件,则将P的右孩子和左孩子依次入栈,当前节点重新置为栈顶结点,之后重复操作2);

4)直到栈空,遍历结束。

a、下面代码比较常规,与上面分析思路一致

 /**
  * Definition for binary tree
  * struct TreeNode {
  *     int val;
  *     TreeNode *left;
  *     TreeNode *right;
  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
  * };
  */
 class Solution {
 public:
     vector<int> postorderTraversal(TreeNode *root) {
         vector<int> postorder_vec;
         TreeNode *cur=root; //定义指针,指向当前节点
         TreeNode *pre=NULL;//定义指针,指向上一各访问的节点
         if(cur==NULL) return postorder_vec;
         stack<TreeNode *> postorder_stack;//创建一个空栈
         postorder_stack.push(cur);//先将树的根节点入栈
         //直到栈空时,结束循环
         while(!postorder_stack.empty())
         {
             cur=postorder_stack.top();//当前节点置为栈顶节点
             if((cur->left==NULL&&cur->right==NULL)||
             ((pre!=NULL)&&(cur->left==pre||cur->right==pre)))
             {
             //如果当前节点没有左右孩子,或者有左孩子或有孩子,但已经被
             //访问输出,则直接输出该节点,将其出栈,将其设为上一个访问的节点
                 postorder_stack.pop();
                 postorder_vec.push_back(cur->val);
                 pre=cur;
             }
             else
             {
                  //如果不满足上面两种情况,则将其右孩子左孩子依次入栈
                 if(cur->right!=NULL) postorder_stack.push(cur->right);
                 if(cur->left!=NULL) postorder_stack.push(cur->left);
             }
         }
     }
 };

b、下面代码简洁(个人感觉,不喜勿喷)

 /**
  * Definition for binary tree
  * struct TreeNode {
  *     int val;
  *     TreeNode *left;
  *     TreeNode *right;
  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
  * };
  */
 class Solution {
 public:
    vector<int> postorderTraversal(TreeNode *root)
     {
         vector<int> rs;
         if (!root) return rs;  //若为空树,则返回空vector
         stack<TreeNode *> stk;
         stk.push(root);  //当前节点入栈
         while (!stk.empty())
         {
             TreeNode *t = stk.top();  //栈顶节点出栈、输出
             stk.pop();
             rs.push_back(t->val);
             //注意,下面入栈顺序不能错 ,因为先左后右,
             //这样出栈时先遍历才是右(中->右->左)
             if (t->left) stk.push(t->left);
             if (t->right) stk.push(t->right);
         }
         reverse(rs.begin(), rs.end());  //逆序,就成了后序遍历了
         return rs;
     }
 };

leetcode题解:Binary Tree Postorder Traversal (二叉树的后序遍历)的更多相关文章

  1. [LeetCode] Binary Tree Postorder Traversal 二叉树的后序遍历

    Given a binary tree, return the postorder traversal of its nodes' values. For example: Given binary ...

  2. lintcode:Binary Tree Postorder Traversal 二叉树的后序遍历

    题目: 二叉树的后序遍历 给出一棵二叉树,返回其节点值的后序遍历. 样例 给出一棵二叉树 {1,#,2,3}, 1 \ 2 / 3 返回 [3,2,1] 挑战 你能使用非递归实现么? 解题: 递归程序 ...

  3. [LeetCode] Binary Tree Inorder Traversal 二叉树的中序遍历

    Given a binary tree, return the inorder traversal of its nodes' values. For example:Given binary tre ...

  4. [LeetCode] Binary Tree Preorder Traversal 二叉树的先序遍历

    Given a binary tree, return the preorder traversal of its nodes' values. For example:Given binary tr ...

  5. 【leetcode】Binary Tree Postorder Traversal (hard) ☆

    二叉树的后序遍历 用标记右子树vector的方法 vector<int> postorderTraversal(TreeNode *root) { vector<int> an ...

  6. Java for LeetCode 145 Binary Tree Postorder Traversal

    Given a binary tree, return the postorder traversal of its nodes' values. For example: Given binary ...

  7. leetcode 145. Binary Tree Postorder Traversal ----- java

    Given a binary tree, return the postorder traversal of its nodes' values. For example:Given binary t ...

  8. leetcode 题解:Binary Tree Preorder Traversal (二叉树的先序遍历)

    题目: Given a binary tree, return the preorder traversal of its nodes' values. For example:Given binar ...

  9. leetcode Binary Tree Postorder Traversal 二叉树后续遍历

    先给出递归版本的实现方法,有时间再弄个循环版的.代码如下: /** * Definition for binary tree * struct TreeNode { * int val; * Tree ...

随机推荐

  1. 【原创】js中input type=file的一些问题

    1.介绍 在开发中,文件上传必不可少,input[type=file] 是常用的上传标签,但是它长得又丑.浏览的字样不能换,但是他长得到底有多丑呢.我们来看看在不同浏览器里的样子吧. <inpu ...

  2. ABAP GET TIME

    用来获得应用服务器的时间. 在程序开始运行的时候,sy-uzeit已经被写入内存,不用get time不会刷新 例如: 运行结果: FORM TSTSYS.   DATA: i1 TYPE i VAL ...

  3. Install Ansible on Mac OSX

    from: https://devopsu.com/guides/ansible-mac-osx.html and : https://devopsu.com/guides/ansible-post- ...

  4. C++学习基础十二——纯虚函数与抽象类

    一.C++中纯虚函数与抽象类: 1.含有一个或多个纯虚函数的类成为抽象类,注意此处是纯虚函数,而不是虚函数. 2.如果一个子类继承抽象类,则必须实现父类中的纯虚函数,否则该类也为抽象类. 3.如果一个 ...

  5. Yii2框架打包成Phar包报错的经历

    以yii2为例 打包文件过程比较简单,但打包好以后简单测试yii命令,一直报错: PHP Fatal error: Uncaught yii\base\InvalidParamException: T ...

  6. APPCAN MAS接口之SOAP

    APPCAN MAS接口中使用webservice接口形式,示例代码如下:  1 var MEAP=require("meap");  2   3 function run(Par ...

  7. SVN 操作指南

    1.安装 和 使用 2.导入导出 2.错误信息 ① svn不知到这样的主机

  8. RHEL5.8设置OpenSSH的X11 Forwarding功能

    X11的Forwarding功能需要在SSH中进行设置,RedHat Enterprise Linux5.8默认使用的而是OpenSSH,现将设置方法记录如下: OpenSSH配置文件路径: /etc ...

  9. 【C#】Color颜色对照表

    Color.AliceBlue 240,248,255 Color.LightSalmon 255,160,122 Color.AntiqueWhite 250,235,215 Color.Light ...

  10. SQL PROMPT 取消dbo前缀

    SQL Prompt 无疑大大提高了开发者的效率,高效而简单,特别适合大型的数据库脚本编写,但遗憾得是至今没有可供使用的中文版本.SQL Prompt 默认对象名前面会有 dbo 前缀,在一些场合这样 ...