94-二叉树中序遍历、538-反向中序遍历、后序遍历(非递归!)

94-二叉树中序遍历

1.递归

class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
    	List<Integer> ans = new ArrayList<>();
        dfs(ans, root);
        return ans;
    }
    public void dfs(List<Integer> ans, TreeNode root){
        if(root == null)
            return;
        dfs(ans, root.left);
        ans.add(root.val);
        dfs(ans,root.right);
    }
}

2.非递归

class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
		//非递归 O(n) O(n)
        List<Integer> ans = new ArrayList<>();
        Stack<TreeNode> st = new Stack<>();
        TreeNode p = root;
        while(p != null || !st.empty()){
            if(p != null){
                st.push(p);
                //ans.add(p.val);//前序遍历
                p = p.left;//一直走到最左边
            }
            else{//p == null && !st.empty()
                p = st.pop();//取出最左边节点
                ans.add(p.val);
                p = p.right;//向右遍历
            }
        }
        return ans;
   }
}

3.Morris中序遍历!

class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        //Morris中序遍历!! O(n) O(1)
        List<Integer> ans = new ArrayList<>();
        TreeNode x = root;
        while(x != null){
            if(x.left == null){//x无左孩子,直接遍历根节点
                ans.add(x.val);
                x = x.right;
            }
            else if(x.left != null){//x有左孩子,找x的predecessor
                TreeNode pre = predecessor(x);
                if(pre.right == null){//还没有添加链接
                    pre.right = x;
                    x = x.left;
                }
                else{//pre.right != null 说明左边已经遍历过了
                    ans.add(x.val);
                    pre.right = null;//断开链接
                    x = x.right;
                }
            }
        }
        return ans;
    }

    public TreeNode predecessor(TreeNode x){
        TreeNode p = x.left;
        while(p.right != null && p.right != x)//注意:此处一定要加条件p.right != x!!否则第二次查predecessor(x)会出现错误
            p = p.right;
        return p;
    }
}

538-反向中序遍历

class Solution {
    int sum = 0;
    public TreeNode convertBST(TreeNode root) {
     //反向中序遍历二叉树!(将中序遍历的左右子树顺序调换即可)
        if(root != null){
            convertBST(root.right);

            //更新当前节点(遍历)
            sum += root.val;
            root.val = sum;

            convertBST(root.left);
        }
        return root;
    }
}
        //morris算法(反向中序遍历) O(n) O(1)
    //     int sum = 0;

    //     TreeNode x = root;
    //     while(x != null){
    //         if(x.right == null){//没有右孩子直接遍历
    //             sum += x.val;
    //             x.val = sum;
    //             x = x.left;
    //         }
    //         else{//有右孩子则找它的predecessor
    //             TreeNode pre = predecessor(x);
    //             if(pre.left == null){
    //                 pre.left = x;
    //                 x = x.right;
    //             }
    //             else{//右边已经遍历过
    //                 sum += x.val;
    //                 x.val = sum;
    //                 pre.left = null;//断链
    //                 x = x.left;
    //             }
    //         }
    //     }
    //     return root;
    // }

    // public TreeNode predecessor(TreeNode x){
    //     TreeNode p = x.right;
    //     while(p.left != null && p.left != x)
    //         p = p.left;
    //     return p;
    // }

二叉树后序遍历(非递归)

public void postOrderTraverse(TreeNode root){
	Deque<TreeNode> st = new LinkedList<>();
	st.push(root);
	//后续遍历需要一个额外的指针对上一个遍历的节点进行标记
	TreeNode lastNode = root;//用于标记上一个被遍历的节点
	while(st.peek() != null){
	    TreeNode p = st.peek();
	    if(p.left != null && p.left != lastNode && p.right != lastNode){//左右节点都还没有被遍历(3个条件缺一不可)
	        st.push(p.left);
	    }
	    else if(p.right != null && p.right != lastNode){
	        st.push(p.right);
	    }
	    else{
	        //遍历
	        leftMaxSum.put(p, Math.max(0, f(p.left)));//舍去负数
	        rightMaxSum.put(p, Math.max(0, f(p.right)));
	        ans = Math.max(ans, p.val+leftMaxSum.get(p)+rightMaxSum.get(p));
	        lastNode = p;//标记
	        st.pop();
	    }
	}
}

你可能感兴趣的:(力扣题解,二叉树,leetcode,算法)