-
学习内容:
- 二叉树(Binary Tree):
- 二叉树的基本概念、遍历方式(前序、中序、后序、层序)。
- 二叉搜索树(BST)的定义与操作。
- 递归(Recursion):
- 递归的基础理论,如何设计递归函数。
- 常见递归问题,如斐波那契数列、全排列等。
- 二叉树(Binary Tree):
-
实践:
- 实现二叉树的基本操作,编写递归函数进行树的遍历。
- 用递归解决树相关问题,如查找树的最小深度、最大深度等。
一、二叉树(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;
}