13.3 树与图算法

面试重要程度:⭐⭐⭐⭐⭐

常见提问方式: "手写二叉树遍历" "实现图的DFS/BFS" "二叉搜索树操作"

预计阅读时间:45分钟

🌳 二叉树基础结构

树节点定义

/**
 * 二叉树节点定义
 */
public class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    
    TreeNode() {}
    TreeNode(int val) { this.val = val; }
    TreeNode(int val, TreeNode left, TreeNode right) {
        this.val = val;
        this.left = left;
        this.right = right;
    }
}

/**
 * N叉树节点定义
 */
public class Node {
    public int val;
    public List<Node> children;
    
    public Node() {}
    public Node(int val) {
        this.val = val;
    }
    public Node(int val, List<Node> children) {
        this.val = val;
        this.children = children;
    }
}

🔄 二叉树遍历

递归遍历

/**
 * 二叉树递归遍历
 */
public class BinaryTreeTraversalRecursive {
    
    /**
     * 前序遍历(根-左-右)
     * LeetCode 144: Binary Tree Preorder Traversal
     */
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        preorderHelper(root, result);
        return result;
    }
    
    private void preorderHelper(TreeNode node, List<Integer> result) {
        if (node == null) return;
        
        result.add(node.val);           // 访问根节点
        preorderHelper(node.left, result);   // 遍历左子树
        preorderHelper(node.right, result);  // 遍历右子树
    }
    
    /**
     * 中序遍历(左-根-右)
     * LeetCode 94: Binary Tree Inorder Traversal
     */
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        inorderHelper(root, result);
        return result;
    }
    
    private void inorderHelper(TreeNode node, List<Integer> result) {
        if (node == null) return;
        
        inorderHelper(node.left, result);    // 遍历左子树
        result.add(node.val);                // 访问根节点
        inorderHelper(node.right, result);   // 遍历右子树
    }
    
    /**
     * 后序遍历(左-右-根)
     * LeetCode 145: Binary Tree Postorder Traversal
     */
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        postorderHelper(root, result);
        return result;
    }
    
    private void postorderHelper(TreeNode node, List<Integer> result) {
        if (node == null) return;
        
        postorderHelper(node.left, result);   // 遍历左子树
        postorderHelper(node.right, result);  // 遍历右子树
        result.add(node.val);                 // 访问根节点
    }
}

迭代遍历

/**
 * 二叉树迭代遍历
 */
public class BinaryTreeTraversalIterative {
    
    /**
     * 前序遍历迭代实现
     */
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        if (root == null) return result;
        
        Stack<TreeNode> stack = new Stack<>();
        stack.push(root);
        
        while (!stack.isEmpty()) {
            TreeNode node = stack.pop();
            result.add(node.val);
            
            // 先压入右子树,再压入左子树(栈的特性)
            if (node.right != null) {
                stack.push(node.right);
            }
            if (node.left != null) {
                stack.push(node.left);
            }
        }
        
        return result;
    }
    
    /**
     * 中序遍历迭代实现
     */
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        Stack<TreeNode> stack = new Stack<>();
        TreeNode current = root;
        
        while (current != null || !stack.isEmpty()) {
            // 一直向左走到底
            while (current != null) {
                stack.push(current);
                current = current.left;
            }
            
            // 处理栈顶元素
            current = stack.pop();
            result.add(current.val);
            
            // 转向右子树
            current = current.right;
        }
        
        return result;
    }
    
    /**
     * 后序遍历迭代实现
     */
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        if (root == null) return result;
        
        Stack<TreeNode> stack = new Stack<>();
        TreeNode lastVisited = null;
        TreeNode current = root;
        
        while (current != null || !stack.isEmpty()) {
            if (current != null) {
                stack.push(current);
                current = current.left;
            } else {
                TreeNode peekNode = stack.peek();
                
                // 如果右子树存在且未被访问过
                if (peekNode.right != null && lastVisited != peekNode.right) {
                    current = peekNode.right;
                } else {
                    result.add(peekNode.val);
                    lastVisited = stack.pop();
                }
            }
        }
        
        return result;
    }
    
    /**
     * 层序遍历(BFS)
     * LeetCode 102: Binary Tree Level Order Traversal
     */
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> result = new ArrayList<>();
        if (root == null) return result;
        
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        
        while (!queue.isEmpty()) {
            int levelSize = queue.size();
            List<Integer> currentLevel = new ArrayList<>();
            
            for (int i = 0; i < levelSize; i++) {
                TreeNode node = queue.poll();
                currentLevel.add(node.val);
                
                if (node.left != null) {
                    queue.offer(node.left);
                }
                if (node.right != null) {
                    queue.offer(node.right);
                }
            }
            
            result.add(currentLevel);
        }
        
        return result;
    }
}

🔍 二叉搜索树操作

BST基础操作

/**
 * 二叉搜索树操作
 */
public class BinarySearchTreeOperations {
    
    /**
     * 验证二叉搜索树
     * LeetCode 98: Validate Binary Search Tree
     */
    public boolean isValidBST(TreeNode root) {
        return isValidBSTHelper(root, Long.MIN_VALUE, Long.MAX_VALUE);
    }
    
    private boolean isValidBSTHelper(TreeNode node, long minVal, long maxVal) {
        if (node == null) return true;
        
        if (node.val <= minVal || node.val >= maxVal) {
            return false;
        }
        
        return isValidBSTHelper(node.left, minVal, node.val) &&
               isValidBSTHelper(node.right, node.val, maxVal);
    }
    
    /**
     * 二叉搜索树中的搜索
     * LeetCode 700: Search in a Binary Search Tree
     */
    public TreeNode searchBST(TreeNode root, int val) {
        if (root == null || root.val == val) {
            return root;
        }
        
        return val < root.val ? searchBST(root.left, val) : searchBST(root.right, val);
    }
    
    /**
     * 二叉搜索树中的插入操作
     * LeetCode 701: Insert into a Binary Search Tree
     */
    public TreeNode insertIntoBST(TreeNode root, int val) {
        if (root == null) {
            return new TreeNode(val);
        }
        
        if (val < root.val) {
            root.left = insertIntoBST(root.left, val);
        } else {
            root.right = insertIntoBST(root.right, val);
        }
        
        return root;
    }
    
    /**
     * 删除二叉搜索树中的节点
     * LeetCode 450: Delete Node in a BST
     */
    public TreeNode deleteNode(TreeNode root, int key) {
        if (root == null) return null;
        
        if (key < root.val) {
            root.left = deleteNode(root.left, key);
        } else if (key > root.val) {
            root.right = deleteNode(root.right, key);
        } else {
            // 找到要删除的节点
            if (root.left == null) {
                return root.right;
            } else if (root.right == null) {
                return root.left;
            } else {
                // 节点有两个子节点,找到右子树的最小节点
                TreeNode minNode = findMin(root.right);
                root.val = minNode.val;
                root.right = deleteNode(root.right, minNode.val);
            }
        }
        
        return root;
    }
    
    private TreeNode findMin(TreeNode node) {
        while (node.left != null) {
            node = node.left;
        }
        return node;
    }
    
    /**
     * 二叉搜索树的最近公共祖先
     * LeetCode 235: Lowest Common Ancestor of a Binary Search Tree
     */
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root == null) return null;
        
        // 如果p和q都在左子树
        if (p.val <

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

Java面试圣经 文章被收录于专栏

Java面试圣经,带你练透java圣经

全部评论
递归和迭代都齐了
点赞 回复 分享
发布于 2025-09-06 08:19 浙江

相关推荐

评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务