3 树的模板

前序: 144 Binary Tree Preorder Traversal(L66)

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 cur = stack.pop();
        res.add(cur.val);

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

        if (cur.left != null) {
            stack.push(cur.left);
        }
    }

    return res;
}

// 递归, traverse, 自己一个人拿着个小本子,每到一个地方,把数据记下来。
// 所以不用返回值,带着本子就行(result)
public List<Integer> postorderTraversal(TreeNode root) {
    List<Integer> result = new ArrayList<>();
    if (root == null) {
        return result;
    }    
    helper(root);
    return result;
}
//1. 递归的入口,把root放到result里
void helper(TreeNode root) {
    // 3. 递归的出口
    if (root == null) {
        return;
    }

    // 2. 递归的拆分
    result.add(root.val);    
    helper(root.left);  
    helper(root.right);   
}

// 递归,Divide & Qonquer, 领导,派2个小弟去把子问题解决,小弟返回以后,
// 领导结合自己的结果再向上汇报,所以D&Q是会return值的
public List<Integer> postorderTraversal(TreeNode root) {
    List<Integer> result = new ArrayList<>();
    if (root == null) {
        return result;
    }

    //Divide
    ArrayList<Integer> left = postorderTraversal(root.left);    
    ArrayList<Integer> right = postorderTraversal(root.right);

    // Conquer
    result.add(root.val);
    result.add(left);
    result.add(right);

    return result;
}

中序: 94 Binary Tree Inorder Traversal (L67)

// 听说是更通用的模板,用这个来做iterator那题
// 可以通过把right改成left,变成prev()的iterator
// 这个prev()可以用在 Closest Binary Search Tree Value II里
public ArrayList<Integer> inorderTraversal(TreeNode root) {
    Stack<TreeNode> stack = new Stack<>();
    ArrayList<Integer> result = new ArrayList<>();
    
    while (root != null) {
        stack.push(root);
        root = root.left;
    }

    while (!stack.isEmpty()) {
        TreeNode node = stack.peek();
        result.add(node.val);
        
        if (node.right == null) {
            node = stack.pop();
            while (!stack.isEmpty() && stack.peek().right == node) {
                node = stack.pop();
            }
        } else {
            node = node.right;
            while (node != null) {
                stack.push(node);
                node = node.left;
            }
        }
    }
    return result;
}

public List<Integer> inorderTraversal(TreeNode root) {
    List<Integer> res = new ArrayList<>();
    TreeNode cur = root;
    Stack<TreeNode> stack = new Stack<>();

    while (cur != null || !stack.isEmpty()) {
        while (cur != null) {
            stack.push(cur);
            cur = cur.left;
        }

        cur = stack.pop();
        res.add(cur.val);
        cur = cur.right;
    }

    return res;
}

// 递归
List<Integer> result = new ArrayList<>();
public List<Integer> postorderTraversal(TreeNode root) {
    if (root == null) {
        return result;
    }

    helper(root);
    return result;
}

void helper(TreeNode root) {
    if (root == null) {
        return;
    }

    if (root.left != null) {
        helper(root.left);
    }
    result.add(root.val);
    if (root.right != null) {
        helper(root.right);
    }    
}

后序 : 145 Binary Tree Postorder Traversal (L68)

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

    Stack<Pair> stack = new Stack<>();
    stack.push(new Pair(root, false));
    while (!stack.isEmpty()) {
        Pair p = stack.pop();
        if (p.node == null) {
            continue;
        }
        if (p.visited) {
            res.add(p.node.val);
        } else {
            stack.push(new Pair(p.node, true));
            stack.push(new Pair(p.node.right, false));
            stack.push(new Pair(p.node.left, false));
        }
    }

    return res;
}


class Pair {
    TreeNode node;
    boolean visited;

    public Pair(TreeNode n, boolean v) {
        node = n;
        visited = v;
    }
}

// 递归
List<Integer> result = new ArrayList<>();
public List<Integer> postorderTraversal(TreeNode root) {
    if (root == null) {
        return result;
    }

    helper(root);
    return result;
}

void helper(TreeNode root) {
    if (root == null) {
        return;
    }

    if (root.left != null) {
        helper(root.left);
    }
    if (root.right != null) {
        helper(root.right);
    }
    result.add(root.val);
}

inorder successor : 285 Inorder Successor in BST (L448)

// 迭代
public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
    TreeNode suc = null;
    while (root != null && p != root) {// find location of p and record posible suc from top
        if (root.val > p.val) {
            suc = root;
            root = root.left;
        } else {
            root = root.right;
        }
    }

    if (root == null) {// p not in tree
        return null;
    }

    if (root.right == null) {// p's right sub tree not exist, so suc must be from top
        return suc;
    }

    root = root.right;
    while (root.left != null) {// p's right subtree exsit, suc is the left most node in right subtree
        root = root.left;
    }

    return root;
}

// 递归
public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
    if (root == null || p == null) {
        return null;
    }

    if (p.val >= root.val) { // 当要找的大于等于跟,我们去右边找
        return inorderSuccessor(root.right, p); 
    } else {// 如果不是的话,那么在左边找
       TreeNode found = inorderSuccessor(root.left, p);
       return found == null ? root : found;// 如果在左边找到就返回,找不到证明根就是successor
    }
}

BST插入:L85 Insert Node in a BST

// 递归 T:O(H), S:O(H), avg H=logn, worst case H=n
public TreeNode insertNode(TreeNode root, TreeNode node) {
    if (root == null) {
        return node;
    }

    if (node.val < root.val) {
        root.left = insertNode(root.left, node);
    } else {
        root.right = insertNode(root.right, node);
    }

    return root;
}

// 迭代, T:O(H), S:O(1), 因为没有递归栈
public TreeNode insertIntoBST(TreeNode root, int val) {
    TreeNode curNode = root;
    while (curNode != null) {
        if (curNode.val > val) { // 插入左边
            if (curNode.left == null) { // 如果已经到叶子了,直接插入
                TreeNode node = new TreeNode(val);
                curNode.left = node;
                return root;
            }
            // 还有左子树,所以走下去
            curNode = curNode.left;
        } else { // 插入右边
            if (curNode.right == null) { // 如果已经到叶子了,直接插入
                TreeNode node = new TreeNode(val);
                curNode.right = node;
                return root;
            }
            // 还有右子树,所以走下去
            curNode = curNode.right;
        }
    }
    
    return new TreeNode(val);
}

BST删除:450 Delete Node in a BST (L87) T:O(n), S:O(height)

public TreeNode removeNode(TreeNode root, int value) {

    if (root == null) {
        return root;
    }

    if (value < root.val) {
        root.left = removeNode(root.left, value);
    } else if (value > root.val) {
        root.right = removeNode(root.right, value);
    } else {
        // the node need to be deleted may be 3 types of node
        // case 1 : leave node, just delete it
        if (root.left == null && root.right == null) {
            return null;
            // case 2 : has single child, replace node with it's child
        } else if (root.left == null && root.right != null) {
            return root.right;
        } else if (root.left != null && root.right == null) {
            return root.left;
        } else {
            // case 3 : have 2 children, need to replace with inorder succesor 
            // then recursively delete child
            TreeNode suc = findSuc(root, value);
            root.val = suc.val;
            // because root has both child, so successor must in the right 
            // subtree
            root.right = removeNode(root.right, suc.val);
        }
    }
    return root;
}

private TreeNode findSuc(TreeNode root, int target) {
    TreeNode suc = null;
    while (root != null && root.val != target) {
        if (root.val > target) {
            suc = root;
            root = root.left;
        } else {
            root = root.right;
        }
    }

    if (root == null) {// target is not in the tree
        return null;
    }

    if (root.right == null) {// if doesn't have right subtree, return successor
        return suc;
    }

    root = root.right;// suc is left most element in right subtree
    while (root.left != null) {
        root = root.left;
    }
    return root;
}

Last updated