145. 二叉树的后序遍历(java实现)--LeetCode

题目:

给定一个二叉树,返回它的 后序 遍历。

示例:

输入: [1,null,2,3]  
   1
    \
     2
    /
   3 

输出: [3,2,1]

进阶: 递归算法很简单,你可以通过迭代算法完成吗?

解法1:递归

    public List<Integer> postorderTraversal(TreeNode root) {
    
    
        ArrayList<Integer> result = new ArrayList<>();
        recursive(result,root);
        return result;
    }

    private void recursive(ArrayList<Integer> result, TreeNode root) {
    
    
        if (root==null)return;
        recursive(result,root.left);
        recursive(result,root.right);
        result.add(root.val);
    }

时间复杂度:On

空间复杂度:On
在这里插入图片描述

解法2:stack

/**
 * 思路:
 * 关键:记录右侧节点是否走过 走到极左 判断右侧节点
 * 
 * 先走到极左
 * 之后判断是否有右侧节点
 * 没有,加入结果集,记录当前节点为右子树,用来判断是否走过右侧,root赋值为null
 * 有,root赋值为root.right
 */
    public List<Integer> postorderTraversal(TreeNode root) {
    
    
        ArrayList<Integer> result = new ArrayList<>();
        ArrayDeque<TreeNode> stack = new ArrayDeque<>();
        //保证右侧不会走第二遍
        TreeNode right_record=null;
        while (!stack.isEmpty()||root!=null){
    
    
            while (root!=null){
    
    
                stack.push(root);
                root=root.left;
            }
            root=stack.pop();
            if (root.right==null||root.right==right_record) {
    
    
                result.add(root.val);
                //记录右子树,用来标记是否走过右侧
                right_record=root;
                root=null;
            }else {
    
    
                stack.push(root);
                root=root.right;
            }
        }
        return result;
    }

时间复杂度:On

空间复杂度:On
在这里插入图片描述

解法3:Morris

/**
 * https://leetcode.com/problems/binary-tree-postorder-traversal/discuss/45648/Three-ways-of-Iterative-PostOrder-Traversing.-Easy-Explanation!
 */
    public static void main(String[] args) {
    
    
        TreeNode t1 = new TreeNode(1);
        TreeNode t2 = new TreeNode(2);
        TreeNode t3 = new TreeNode(3);
        TreeNode t4 = new TreeNode(4);
        TreeNode t5 = new TreeNode(5);
        TreeNode t6 = new TreeNode(6);
        t1.left=t2;
        t1.right=t3;
        t2.right=t4;
        t4.left=t5;
        t4.right=t6;
        postorderTraversal(t1);
    }
    static class TreeNode{
    
    
        int val;
        TreeNode left,right;
        public TreeNode(int val){
    
    
            this.val=val;
        }
        public TreeNode(TreeNode left, TreeNode right, int val){
    
    
            this.left=left;
            this.right=right;
            this.val=val;
        }
    }
    public static List<Integer> postorderTraversal(TreeNode root) {
    
    
        List<Integer> result = new ArrayList<Integer>();
        TreeNode dummy = new TreeNode(-1);
        TreeNode pre = null;
        dummy.left = root;
        root = dummy;
        while (root!=null){
    
    
            if (root.left!=null){
    
    
                pre = root.left;
                while(pre.right != null && pre.right != root)
                    pre=pre.right;
                if(pre.right == null){
    
    
                    pre.right = root;
                    root = root.left;
                } else{
    
    
                    TreeNode node = pre;
                    reverse(root.left,pre);
                    while(node != root.left){
    
    
                        result.add(node.val);
                        node = node.right;
                    }
                    result.add(node.val);          // Print again since we are stopping at node=root.left
                    reverse(pre,root.left);
                    pre.right = null;
                    root = root.right;
                }
            }else {
    
    
                root=root.right;
            }
        }
        return result;
    }

    public static void reverse(TreeNode rootLeft, TreeNode pre){
    
    
        if(rootLeft == pre)
            return;
        TreeNode prev = rootLeft, node = rootLeft.right;
        while(prev != pre){
    
    
            TreeNode next = node.right;
            node.right = prev;
            prev = node;
            node = next;
        }
    }

时间复杂度:On

空间复杂度:On
在这里插入图片描述

解法4:颜色遍历

/**
 * 思路:
 * 颜色标记,0是没走过,1是走过
 * 在栈中存放paris 0/1,node
 * 如果当前节点是没走过,按照根右左的顺序加入栈中
 */
    public List<Integer> postorderTraversal(TreeNode root) {
    
    
        ArrayList<Integer> result = new ArrayList<>();
        if (root==null)return result;
        ArrayDeque<Pair<Integer,TreeNode>> stack = new ArrayDeque<>();
        stack.push(new Pair<>(0,root));
        while (!stack.isEmpty()){
    
    
            Pair<Integer, TreeNode> pop = stack.pop();
            if (pop.getKey()==0) {
    
    
                stack.push(new Pair<>(1, pop.getValue()));
                if (pop.getValue().right!=null) stack.push(new Pair<>(0, pop.getValue().right));
                if (pop.getValue().left!=null) stack.push(new Pair<>(0, pop.getValue().left));
            }else {
    
    
                result.add(pop.getValue().val);
            }
        }
        return result;
    }

时间复杂度:On

空间复杂度:On
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_38783664/article/details/112061294