二叉树 leetcode (代码随想录)

二叉树理论基础

满二叉树:总共有k层,则节点总数为2^k - 1。根节点为第一层。
完全二叉树:除了最后一层,其余的都是满二叉树。并且最下面一层从左到右连续。
二叉搜索树:设x为二叉树中的一个节点,x节点包含关键字Key,节点x的Key值记为Key[x]。如果y是x的左子树中的一个节点,则Key[y]<=Key[x];如果y是x的有子树的一个节点,则Key[y]>=Key[x]。
平衡二叉搜索树:左右子树的高度差不能超过1。Java中TreeMap底层的红黑树也是一种平衡二叉树。
可以转换为线性存储的数组:root的下标为i 则左孩子:2i+1;右孩子:2i+2(使用前序遍历)。
遍历方式:
1.深度优先搜索(二叉树的前、中、后序遍历)
利用递归的方式实现。也可利用迭代法实现。
2.广度优先搜索(层序遍历)
利用迭代法实现。依赖队列实现。

二叉树的遍历:


思路一:递归
leetcode 144 二叉树的前序遍历
/**
 * Definition for a binary tree node.
 * 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;
 *     }
 * }
 */
public List<Integer> preorderTraversal(TreeNode root) {
    List<Integer> result = new ArrayList<>();
    preorder(root, result);
    return result;
}

private void preorder(TreeNode node, List<Integer> result) {
    if (node == null) return;
    result.add(node.val);       // 访问根节点
    preorder(node.left, result); // 遍历左子树
    preorder(node.right, result);// 遍历右子树
}
leetcode 145 二叉树的后序遍历
public List<Integer> postorderTraversal(TreeNode root) {
    List<Integer> result = new ArrayList<>();
    postorder(root, result);
    return result;
}

private void postorder(TreeNode node, List<Integer> result) {
    if (node == null) return;
    postorder(node.left, result);  // 遍历左子树
    postorder(node.right, result); // 遍历右子树
    result.add(node.val);          // 访问根节点
}
leetcode 94 二叉树的中序遍历
public List<Integer> inorderTraversal(TreeNode root) {
    List<Integer> result = new ArrayList<>();
    inorder(root, result);
    return result;
}

private void inorder(TreeNode node, List<Integer> result) {
    if (node == null) return;
    inorder(node.left, result);  // 遍历左子树
    result.add(node.val);        // 访问根节点
    inorder(node.right, result); // 遍历右子树
}
思路二:迭代
leetcode 144 二叉树的前序遍历
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;
}
leetcode 145 二叉树的后序遍历
public List<Integer> postorderTraversal(TreeNode root) {
    List<Integer> result = new ArrayList<>();
    if (root == null) return result;

    Stack<TreeNode> stack = new Stack<>();
    Stack<TreeNode> output = new Stack<>(); // 辅助栈
    stack.push(root);
    
    while (!stack.isEmpty()) {
        TreeNode node = stack.pop();
        output.push(node);
        if (node.left != null) stack.push(node.left);   // 先左后右
        if (node.right != null) stack.push(node.right);
    }
    
    while (!output.isEmpty()) {
        result.add(output.pop().val);  // 反向输出
    }
    return result;
}
leetcode 94 二叉树的中序遍历
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;
}
时间与空间复杂度

时间复杂度:所有遍历方法均为 O(n),其中 n 是节点总数。

空间复杂度:递归:O(h),其中 h 是树的高度。迭代:O(h),由于使用了栈来保存节点。

总结

前序遍历 常用于拷贝树或表达式求值。

中序遍历 常用于生成升序排序的序列。

后序遍历 常用于删除或释放内存。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值