【左神算法】二叉樹的先序、中序、後序遍歷,包括遞歸方式和非遞歸方式

二叉樹的先序、中序、後序遍歷,包括遞歸方式和非遞歸方式

1、二叉樹的前序遍歷

1.1 思路:

二叉樹是一個由left子節點和right子節點 以及val組成的數據結果。而前序遍歷的過程就是 根左右。
而實現前序遍歷,我們可以用兩種方式一種是遞歸實現,先添加val,遞歸左右子節點。一種非遞歸實現,
遞歸的實現就是系統幫我們自行壓棧操作,因此可以藉助棧結構來實現。先添加root節點,當棧不爲null 保存root.val 以及壓入左子節點和右子節點。如此反覆。
時間複雜度:二叉樹的遍歷需要花費O(n) 如果不計算棧的消耗
空間複雜度:O(n) 無論是遞歸還是非遞歸 都需要進行O(n)

1.2 遞歸實現 code

 //棧
    public List<Integer> preorderTraversal(TreeNode root) {
        ArrayList<Integer> res = new ArrayList<>(); 
        if(root == null)    return res;

        Stack<TreeNode> stack = new Stack();
        stack.push(root);

        while(!stack.isEmpty()){
            TreeNode node = stack.pop();
            res.add(node.val);

            if(node.right!=null){
                stack.push(node.right);
            }

            if(node.left != null){
                stack.push(node.left);
            }            
        }  
        return res;
    }

1.3 非遞歸實現 code

public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        if(root == null)    return res;
        Stack<TreeNode> stack = new Stack<>();
        stack.push(root);
        while(!stack.isEmpty()){
            TreeNode node = stack.pop();
            res.add(node.val);
            if(node.right != null){
                stack.push(node.right);
            }

            if(node.left != null){
                stack.push(node.left);
            }
        }
        return res;
    }

2、二叉樹的中序遍歷

2.1 思路:

中序遍歷和前序遍歷的遞歸版相似,只需要修改添加的位置。
而非遞歸版藉助棧 先壓入左子節點,如果左子節點爲null 彈出 添加值,然後查看右子節點。
時間複雜度:O(n)
空間複雜度:O(n)

2.2 遞歸實現 code

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

    public static void helper(TreeNode root,List<Integer> result){
        if(root!=null){
            //左
            if(root.left!=null){
                helper(root.left,result);
            }
            //中
            result.add(root.val);
            //右
            if(root.right!=null){
                helper(root.right,result);
            }
        }
    }

2.3 非遞歸實現 code

	//藉助stack
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        if(root == null)    return res;
        Stack<TreeNode> stack = new Stack<>();
        TreeNode cur = root;
        while( cur!=null || !stack.empty()){
            //添加左節點
            while(cur!=null){
                stack.push(cur);
                cur = cur.left;
            }
            cur = stack.pop();
            res.add(cur.val);
            //push右節點
            cur = cur.right;
        }
        return res;
    }

3、二叉樹的後序遍歷

3.1 思路:

遞歸版 直接 修改add的位置
非遞歸版 後序遍歷 爲 左右根 而前序遍歷爲根左右 有沒有發現 如果將左右的位置改變 然後在逆序就是後序遍歷的結果了。這裏藉助兩個棧。一個棧存儲節點,另一個棧存儲數據,將根右左的值添加 然後pop 就是結果。
時間複雜度:O(n)
空間複雜度:O(n)

3.2 遞歸實現 code

public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        if(root == null)    return res;
        helper(root,res);
        return res;
    }

    public void helper(TreeNode node,List<Integer> res){
        if(node!=null){
            if(node.left!=null){
                helper(node.left,res);
            }

            if(node.right!=null){
                helper(node.right,res);
            }
            res.add(node.val);
        }
    }

3.3 非遞歸實現 code

	//左右根   先序遍歷 根左右    根右左 
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        if(root==null)  return res;
        Stack<Integer> stack = new Stack();//存儲數據
        Stack<TreeNode> nodeStack = new Stack();//存儲節點

        nodeStack.push(root); //先存儲根節點
        while(!nodeStack.isEmpty()){
            TreeNode node = nodeStack.pop();
            stack.push(node.val);
            if(node.left!=null){
                nodeStack.push(node.left);
            }

            if(node.right!=null){
                nodeStack.push(node.right);
            }
        }
        while(!stack.isEmpty()){
            res.add(stack.pop());
        }
        return res;
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章