1. 程式人生 > >Tree Traversal(樹的遍歷)

Tree Traversal(樹的遍歷)

(一)Binary Tree Preorder Traversal 

https://leetcode.com/problems/binary-tree-preorder-traversal/description/

題目:給定二叉樹,返回其前序遍歷(根左右);

解答:使用棧或者遞迴;

程式碼:

*************棧****************

class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        Stack<TreeNode> stack = new Stack<>();
        stack.push(root);
        
        if (root == null) {
            return res;
        }
        
        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;
    }
}

************遞迴***************

class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        recursion(res, root);
        return res;
    }
    
    private void recursion(List<Integer> list, TreeNode node) {
        if (node == null) {
            return;
        }
        
        list.add(node.val);
        if (node.left != null) {
            recursion(list, node.left);
        }
        if (node.right != null) {
            recursion(list, node.right);
        }
    }
}

(二)Binary Tree Inorder Traversal 

https://leetcode.com/problems/binary-tree-inorder-traversal/description/

題目:給定二叉樹,返回其中序遍歷(左根右);

解答:使用棧;

程式碼:

class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> res = new LinkedList<>();
        Stack<TreeNode> stack = new Stack<>();
        TreeNode node = root;
        
        while(!stack.isEmpty() || node != null) {
            while (node != null) {
                stack.push(node); 
                node = node.left;
            }
            node = stack.pop();
            res.add(node.val);
            node = node.right;
        }
        return res;
    }
}


(三)Binary Tree Postorder Traversal 

https://leetcode.com/problems/binary-tree-postorder-traversal/description/

題目:給定二叉樹,返回其後序遍歷(左右根);

解答:使用棧或者遞迴;

程式碼:

**********************遞迴*************************

class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        
        if (root == null) {
            return res;
        }
        
        res.addAll(postorderTraversal(root.left));
        res.addAll(postorderTraversal(root.right));
        res.add(root.val);
        return res;
    }
}

***********************棧*******************************

class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        
        if (root == null) {
            return res;
        }
        
        Stack<TreeNode> stack = new Stack<>();
        stack.push(root);
        TreeNode prev = null;
        
        while (!stack.isEmpty()) {
            TreeNode curr = stack.peek();
            if (prev == null || prev.right == curr || prev.left == curr) {
                if (curr.left != null) {
                    stack.push(curr.left);
                } else if (curr.right != null) {
                    stack.push(curr.right);
                }
            } else if (curr.left == prev) {
                if (curr.right != null) {
                   stack.push(curr.right);
                }
                
            } else {
                res.add(curr.val);
                stack.pop();
            }
            prev = curr;
        }
        
        return res;
    }
}

(四)Binary Search Tree Iteration

https://leetcode.com/problems/binary-search-tree-iterator/description/

題目:實現二叉查詢樹迭代器,next()返回下一個最小值。要求next()和hasNext()函式的時間、空間複雜度分別為O(1)和O(h),h表示樹的高度;

解答:(二叉查詢樹為有序二叉樹,左節點均小於根節點,右節點均大於根節點)因此,最小的數即為最左的節點。

             1、將二叉樹中所有左節點壓入棧中(初始化);

             2、若棧為空, hasNext返回真;

             3、當前棧的最上面元素pop出來,即為下一個最小值;此時需要判斷pop出的節點是否存在左子樹,若存在,則需要將其左子樹的所有左節點pop入棧(為下一個最小值做                    準備)。

程式碼:

public class BSTIterator {
    Stack<TreeNode> stack = new Stack<>();


    public BSTIterator(TreeNode root) {
        addAllLeft(root);
    }


    /** @return whether we have a next smallest number */
    public boolean hasNext() {
        return !stack.isEmpty();
    }


    /** @return the next smallest number */
    public int next() {
        TreeNode node = stack.pop();
        if (node.right != null) {
            addAllLeft(node.right);
        }
        return node.val;
    }
    
    private void addAllLeft(TreeNode node) {
        while (node != null) {
            stack.push(node);
            node = node.left;
        }
    }
}