树结构与递归的学习笔记

  • 学习内容:

    • 二叉树(Binary Tree):
      • 二叉树的基本概念、遍历方式(前序、中序、后序、层序)。
      • 二叉搜索树(BST)的定义与操作。
    • 递归(Recursion):
      • 递归的基础理论,如何设计递归函数。
      • 常见递归问题,如斐波那契数列、全排列等。
  • 实践:

    • 实现二叉树的基本操作,编写递归函数进行树的遍历。
    • 用递归解决树相关问题,如查找树的最小深度、最大深度等。
一、二叉树(Binary Tree)
1. 基本概念
  • 二叉树: 每个节点最多有两个子节点的树形结构,子节点分为左子节点和右子节点。
  • 根节点(Root Node): 二叉树的顶点。
  • 叶子节点(Leaf Node): 没有子节点的节点。
  • 内部节点(Internal Node): 至少有一个子节点的节点。
  • 高度(Height): 从节点到叶子的最长路径长度。
  • 深度(Depth): 从根节点到该节点的路径长度。
2. 二叉树的遍历方式
  • 前序遍历(Pre-order Traversal): 按照“根节点 -> 左子树 -> 右子树”的顺序访问节点。
  • 中序遍历(In-order Traversal): 按照“左子树 -> 根节点 -> 右子树”的顺序访问节点。
  • 后序遍历(Post-order Traversal): 按照“左子树 -> 右子树 -> 根节点”的顺序访问节点。
  • 层序遍历(Level-order Traversal): 按照从根节点开始,自上而下逐层访问节点(广度优先搜索)。
3. 二叉搜索树(BST)
  • 定义: 对于二叉搜索树,任意节点的左子树中所有节点的值均小于该节点的值,右子树中所有节点的值均大于该节点的值。
  • 基本操作:
    • 插入: 插入新节点时,根据节点值大小,将其放在合适的位置,确保BST的性质不被破坏。
    • 查找: 从根节点开始,逐层比较节点值,找到目标节点。
    • 删除: 删除节点分三种情况处理:删除叶子节点、删除只有一个子节点的节点、删除有两个子节点的节点。

二、递归(Recursion)
1. 基础理论
  • 递归: 函数直接或间接调用自身来解决问题的编程技术。
  • 递归条件:
    • 基准情况(Base Case): 递归结束的条件,避免无限递归。
    • 递归关系(Recursive Case): 解决更小规模问题的过程。
2. 常见递归问题
  • 斐波那契数列: 通过递归计算第n个斐波那契数。
  • 全排列: 利用递归生成一个序列的所有排列方式。

实践部分

1. 实现二叉树的基本操作
class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    TreeNode(int val) {
        this.val = val;
    }
}

// 前序遍历
void preOrderTraversal(TreeNode node) {
    if (node == null) return;
    System.out.print(node.val + " ");
    preOrderTraversal(node.left);
    preOrderTraversal(node.right);
}

// 中序遍历
void inOrderTraversal(TreeNode node) {
    if (node == null) return;
    inOrderTraversal(node.left);
    System.out.print(node.val + " ");
    inOrderTraversal(node.right);
}

// 后序遍历
void postOrderTraversal(TreeNode node) {
    if (node == null) return;
    postOrderTraversal(node.left);
    postOrderTraversal(node.right);
    System.out.print(node.val + " ");
}

// 层序遍历
void levelOrderTraversal(TreeNode root) {
    if (root == null) return;
    Queue<TreeNode> queue = new LinkedList<>();
    queue.add(root);
    while (!queue.isEmpty()) {
        TreeNode node = queue.poll();
        System.out.print(node.val + " ");
        if (node.left != null) queue.add(node.left);
        if (node.right != null) queue.add(node.right);
    }
}
2. 用递归解决树相关问题
// 查找树的最大深度
int maxDepth(TreeNode root) {
    if (root == null) return 0;
    int leftDepth = maxDepth(root.left);
    int rightDepth = maxDepth(root.right);
    return Math.max(leftDepth, rightDepth) + 1;
}

// 查找树的最小深度
int minDepth(TreeNode root) {
    if (root == null) return 0;
    int leftDepth = minDepth(root.left);
    int rightDepth = minDepth(root.right);
    return (leftDepth == 0 || rightDepth == 0) ? leftDepth + rightDepth + 1 : Math.min(leftDepth, rightDepth) + 1;
}

// 递归实现斐波那契数列
int fibonacci(int n) {
    if (n <= 1) return n;
    return fibonacci(n - 1) + fibonacci(n - 2);
}

// 递归生成全排列
void permute(int[] nums, int start, List<List<Integer>> result) {
    if (start == nums.length) {
        List<Integer> list = new ArrayList<>();
        for (int num : nums) list.add(num);
        result.add(list);
        return;
    }
    for (int i = start; i < nums.length; i++) {
        swap(nums, start, i);
        permute(nums, start + 1, result);
        swap(nums, start, i);
    }
}

void swap(int[] nums, int i, int j) {
    int temp = nums[i];
    nums[i] = nums[j];
    nums[j] = temp;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值