145. 二叉树的后序遍历

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

Example:

Input: [1,null,2,3]
   1
    \
     2
    /
   3

Output: [3,2,1]

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

二叉树的后序遍历。后序遍历我记为左 - 右 - 中

 

 

 Postorder (Left, Right, Root) : 4 5 2 3 1

递归实现:

class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> list=new ArrayList<>();
        if(root==null){
            return list;
        }
        process(root,list);
        return list;
    }

    public void process(TreeNode node,List<Integer> list){
        if(node==null){
            return;
        }
        process(node.left,list);
        process(node.right,list);
        list.add(node.val);

    }
}

  

非递归实现:

后:左右中
用两stack来实现
第一个入栈的顺序:中(弹出,放入第二个栈中),左右节点入栈
通过上面的步骤则第二个栈的入栈的顺序为:中右左
再依次将第二个栈的弹出,则弹出的顺序是->左右中

class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> list=new ArrayList<>();
        if(root==null){
            return list;
        }
       Stack<TreeNode> s1=new Stack<>();
       Stack<TreeNode> s2=new Stack<>();
       s1.push(root);
       while(!s1.isEmpty()){
           TreeNode cur=s1.pop();
           s2.push(cur);
           if(cur.left!=null){
               s1.push(cur.left);
           }
           if(cur.right!=null){
               s1.push(cur.right);
           }
       }
       while(!s2.isEmpty()){
           list.add(s2.pop().val);
       }
       return list;
    }
}

  

Morris 改后序
1、处理时机在第二次来到cur时:逆序打印左树的右边界
2、最后逆序打印整颗树的右边界
  class Solution {
        public List<Integer> postorderTraversal(TreeNode head) {
            List<Integer> list=new ArrayList<>();
            if(head==null){
                return list;
            }
            TreeNode cur=head;
            TreeNode mostRight;
            while(cur!=null){
                mostRight=cur.left;
                if(mostRight!=null){
                    //有左节点
                    while (mostRight.right!=null&&mostRight.right!=cur){
                        mostRight=mostRight.right;
                    }
                    if(mostRight.right==null){
                        //第一次来到cur
                        mostRight.right=cur;
                        cur=cur.left;
                        continue;
                    }else{
                        //第二次来到cur
                        mostRight.right=null;
                        processEdge(cur.left,list);
                    }
                }

                cur=cur.right;
            }
            processEdge(head,list);
            return list;
        }
    }


    public void processEdge(TreeNode head,List<Integer> list){
        TreeNode tail=reverse(head);
        TreeNode cur=tail;
        while (cur!=null){
            list.add(cur.val);
            cur=cur.right;
        }
        reverse(tail);
    }

    //相当于单链表反转,把right指针当作是next指针
    public TreeNode reverse(TreeNode head){
        if(head==null||head.right==null){
            return head;
        }
        TreeNode pre=null;
        TreeNode next;
        TreeNode cur=head;
        while (cur!=null){
            next=cur.right;
            cur.right=pre;
            pre=cur;
            cur=next;
        }
        return pre;

    }

  



 

posted @ 2021-08-31 21:26  sherry001  阅读(13)  评论(0编辑  收藏  举报