zoukankan      html  css  js  c++  java
  • LeetCode解题报告:Binary Tree Postorder Traversal

    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.递归算法的递归定义是:

    若二叉树为空,则遍历结束;否则
    ⑴ 后序遍历左子树(递归调用本算法);
    ⑵ 后序遍历右子树(递归调用本算法) ;
    ⑶ 访问根结点 。

    对有n个结点的二叉树,其时间复杂度均为O(n) 。

    1 List<Integer> postOrder = new ArrayList<Integer>();
    2 public List<Integer> postorderRecursion(TreeNode root) {
    3         if ((root != null) && (root.val != '#')) {
    4             postorderRecursion(root.left);
    5             postorderRecursion(root.right);
    6             postOrder.add(root.val);
    7         }
    8         return postOrder;
    9     }

    2.非递归算法

       在后序遍历中,根结点是最后被访问的。因此,在遍历过程中,当搜索指针指向某一根结点时,不能立即访问,而要先遍历其左子树,此时根结点进栈。当其左子树遍历完后再搜索到该根结点时,还是不能访问,还需遍历其右子树。所以,此根结点还需再次进栈,当其右子树遍历完后再退栈到到该根结点时,才能被访问。

        因此,设立一个状态标志变量tag :{ 0 : 结点暂不能访问;1 : 结点可以被访问}。

       其次,设两个堆栈S1、S2 ,S1保存结点,S2保存结点的状态标志变量tag 。S1和S2共用一个栈顶指针。

          设T是指向根结点的指针变量,非递归算法是:

    若二叉树为空,则返回;否则,令p=T;

    ⑴ 第一次经过根结点p,不访问:

         p进栈S1 , tag 赋值0,进栈S2,p=p->Lchild 。

    ⑵ 若p不为空,转(1),否则,取状态标志值tag :

     ⑶ 若tag=0:对栈S1,不访问,不出栈;修改S2栈顶元素值(tag赋值1) ,取S1栈顶元素的右子树,即p=S1[top]->Rchild ,转(1);

    ⑷ 若tag=1:S1退栈,访问该结点;

    直到栈空为止。

     1 List<Integer> postOrder = new ArrayList<Integer>();
     2 public List<Integer> postorderTraversal(TreeNode p) {
     3         Stack<TreeNode> stack = new Stack<TreeNode>();
     4         Stack<Boolean> tag = new Stack<Boolean>();
     5         while ((p != null) || !stack.isEmpty()) {
     6             if (p != null) {
     7                 stack.push(p);
     8                 tag.push(false);
     9                 p = p.left;
    10             } else {
    11                 boolean visit = tag.pop();
    12                 if (visit) {
    13                     postOrder.add(stack.pop().val);
    14                 } else {
    15                     tag.push(true);
    16                     p = stack.peek().right;
    17                 }
    18             }
    19         }
    20         return postOrder;
    21     }

    二叉树的三种遍历递归和非递归实现:递归实现都简单;非递归的前序和中序实现简单,后序采用2个栈来实现(参考严蔚敏的思路,比较容易理解)。代码如下:

      1 import java.util.ArrayList;
      2 import java.util.List;
      3 import java.util.Stack;
      4 
      5 import javax.swing.text.AbstractDocument.LeafElement;
      6 
      7 /**
      8  * Definition for binary tree public class TreeNode { int val; TreeNode left;
      9  * TreeNode right; TreeNode(int x) { val = x; } }
     10  */
     11 public class TreeNodeSolution {
     12 
     13     public List<Integer> preorderRecursion(TreeNode root) {
     14         List<Integer> preOrder = new ArrayList<Integer>();
     15         if ((root != null) && (root.val != '#')) {
     16             preOrder.add(root.val);
     17             postorderRecursion(root.left);
     18             postorderRecursion(root.right);
     19         }
     20         return preOrder;
     21     }
     22 
     23     public List<Integer> inorderRecursion(TreeNode root) {
     24         List<Integer> inOrder = new ArrayList<Integer>();
     25         if ((root != null) && (root.val != '#')) {
     26             postorderRecursion(root.left);
     27             inOrder.add(root.val);
     28             postorderRecursion(root.right);
     29         }
     30         return inOrder;
     31     }
     32 
     33     public List<Integer> postorderRecursion(TreeNode root) {
     34         List<Integer> postOrder = new ArrayList<Integer>();
     35         if ((root != null) && (root.val != '#')) {
     36             postorderRecursion(root.left);
     37             postorderRecursion(root.right);
     38             postOrder.add(root.val);
     39         }
     40         return postOrder;
     41     }
     42 
     43     public List<Integer> inorderTraversal(TreeNode p) {
     44         List<Integer> inOrder = new ArrayList<Integer>();
     45         Stack<TreeNode> stack = new Stack<TreeNode>();
     46         while ((p != null) || !stack.isEmpty()) {
     47             if (p != null) {
     48                 stack.push(p);
     49                 p = p.left;
     50             } else {
     51                 p = stack.pop();
     52                 inOrder.add(p.val);
     53                 p = p.right;
     54             }
     55         }
     56         return inOrder;
     57     }
     58 
     59     public List<Integer> preorderTraversal(TreeNode p) {
     60         List<Integer> preOrder = new ArrayList<Integer>();
     61         Stack<TreeNode> stack = new Stack<TreeNode>();
     62         while ((p != null) || !stack.isEmpty()) {
     63             if (p != null) {
     64                 preOrder.add(p.val);
     65                 stack.push(p);
     66                 p = p.left;
     67             } else {
     68                 p = stack.pop();
     69                 p = p.right;
     70             }
     71         }
     72         return preOrder;
     73     }
     74 
     75     public List<Integer> postorderTraversal(TreeNode p) {
     76         List<Integer> postOrder = new ArrayList<Integer>();
     77         Stack<TreeNode> stack = new Stack<TreeNode>();
     78         Stack<Boolean> tag = new Stack<Boolean>();
     79         while ((p != null) || !stack.isEmpty()) {
     80             if (p != null) {
     81                 stack.push(p);
     82                 tag.push(false);
     83                 p = p.left;
     84             } else {
     85                 boolean visit = tag.pop();
     86                 if (visit) {
     87                     postOrder.add(stack.pop().val);
     88                 } else {
     89                     tag.push(true);
     90                     p = stack.peek().right;
     91                 }
     92             }
     93         }
     94         return postOrder;
     95     }
     96 
     97     public static void main(String[] args) {
     98         TreeNode t1 = new TreeNode(1);
     99         TreeNode t2 = new TreeNode(2);
    100         TreeNode t3 = new TreeNode(3);
    101         t1.setRight(t2);
    102         t1.setLeft(t3);
    103         System.out.println(new TreeNodeSolution().postorderTraversal(t1));
    104     }
    105 }
    View Code
  • 相关阅读:
    JS 中 原生方法 (四) --- Object
    在 JavaScript 中 prototype 和 __proto__ 有什么区别
    VueJs 源码分析 ---(一) 整体对 vuejs 框架的理解
    Node.js API 初解读(三)
    npm 包的 发布 流程
    JS 中 原生方法 (三) --- Date 日期
    JS 中 原生方法 (二) --- 数组 (修---添加ES6新增)
    Mac 下VIM配置
    css预处理器(sass)
    BFC 神奇背后的原理
  • 原文地址:https://www.cnblogs.com/byrhuangqiang/p/3790857.html
Copyright © 2011-2022 走看看