一、二叉树深度优先遍历(DFS)——递归方法
1. 前序遍历 (Pre-order Traversal):根-左-右
public class BinaryTree {
public void preOrder(TreeNode node) {
if (node == null) {
return;
}
System.out.print(node.value + " "); // 访问根节点
preOrder(node.left); // 递归遍历左子树
preOrder(node.right); // 递归遍历右子树
}
}
2. 中序遍历 (In-order Traversal):左-根-右
public class BinaryTree {
public void inOrder(TreeNode node) {
if (node == null) {
return;
}
inOrder(node.left); // 递归遍历左子树
System.out.print(node.value + " "); // 访问根节点
inOrder(node.right); // 递归遍历右子树
}
}
3. 后序遍历 (Post-order Traversal):左-右-根
public class BinaryTree {
public void postOrder(TreeNode node) {
if (node == null) {
return;
}
postOrder(node.left); // 递归遍历左子树
postOrder(node.right); // 递归遍历右子树
System.out.print(node.value + " "); // 访问根节点
}
}
二、二叉树深度优先遍历(DFS)——迭代方法
1. 前序遍历 (Pre-order Traversal):根-左-右
import java.util.Stack;
public class BinaryTree {
public void preOrderIterative(TreeNode root) {
if (root == null) {
return;
}
//构造一个【栈】
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()) {
TreeNode node = stack.pop();
System.out.print(node.value + " "); // 访问根节点
if (node.right != null) {//后访问右节点,所以要先压入右节点
stack.push(node.right);
}
if (node.left != null) {
stack.push(node.left);//先访问左节点,所以要后压入左节点
}
}
}
}
2. 中序遍历 (In-order Traversal):左-根-右
public class BinaryTree {
public void inOrderIterative(TreeNode root) {
//构造一个【栈】
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();
System.out.print(current.value + " "); //访问左节点或者根节点
current = current.right; //指向右节点
}
}
}
3. 后序遍历 (Post-order Traversal):左-右-根
把“左右根”的顺序变为“根右左”,遍历后再倒序输出就得到了后序遍历(左右根)的结果。
import java.util.LinkedList;
public class BinaryTree {
public void postOrderIterative(TreeNode root) {
if (root == null) {
return;
}
//构造一个【栈】
Stack<TreeNode> stack = new Stack<>();
LinkedList<Integer> result = new LinkedList<>();
stack.push(root);
while (!stack.isEmpty()) {
TreeNode node = stack.pop();
result.addFirst(node.value); // 插入到列表头部,实现倒序
if (node.left != null) {//后访问左节点,所以要先压入左节点
stack.push(node.left);
}
if (node.right != null) {//先访问右节点,所以要后压入右节点
stack.push(node.right);
}
}
//查看结果
for (Integer value : result) {
System.out.print(value + " ");
}
}
}
三、二叉树广度优先遍历(BFS)
BFS按照层次遍历树,从根节点开始逐层访问每一个节点。BFS 通常使用队列来实现。
import java.util.LinkedList;
import java.util.Queue;
public class BinaryTree {
public void bfs(TreeNode root) {
if (root == null) {
return;
}
//构造一个【队列】
Queue<TreeNode> queue = new LinkedList<>();
// offer:如果插入成功,返回 true;如果队列已满,无法插入,则返回 false。
// 对于基于容量的队列(如 ArrayBlockingQueue),如果队列已满,该方法不会抛出异常,而是返回 false。
queue.offer(root);
while (!queue.isEmpty()) {
//poll:如果队列不为空,返回队列头部的元素;如果队列为空,则返回 null。
TreeNode node = queue.poll();
System.out.print(node.value + " "); // 访问节点
if (node.left != null) {
queue.offer(node.left); // 将左子节点加入队列
}
if (node.right != null) {
queue.offer(node.right); // 将右子节点加入队列
}
}
}
}
四、二叉树最大深度
求一个二叉树的最大深度可以通过递归和迭代两种方法实现。最大深度是从根节点到叶节点的最长路径上的节点数。
1.递归方式
递归方法非常直观。可以通过递归计算每个节点的左子树和右子树的深度,取较大者再加上1,即为该节点的深度。
public class BinaryTree {
//递归方式,求解二叉树最大深度
public 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;
}
}
2.迭代方式
迭代方法通常使用广度优先搜索(BFS)来实现,可以通过层次遍历来计算二叉树的深度。
import java.util.LinkedList;
import java.util.Queue;
public class BinaryTree {
public int maxDepth(TreeNode root) {
if (root == null) {
return 0;
}
Queue<TreeNode> queue = new LinkedList<>();
// offer:如果插入成功,返回 true;如果队列已满,无法插入,则返回 false。
// 对于基于容量的队列(如 ArrayBlockingQueue),如果队列已满,该方法不会抛出异常,而是返回 false。
queue.offer(root);
int depth = 0; //记录二叉树的深度
while (!queue.isEmpty()) {
int levelSize = queue.size(); //每一层的节点数
//遍历当前层的所有节点
for (int i = 0; i < levelSize; i++) {
//poll:如果队列不为空,返回队列头部的元素;如果队列为空,则返回 null。
TreeNode node = queue.poll();
if (node.left != null) {
queue.offer(node.left);
}
if (node.right != null) {
queue.offer(node.right);
}
}
depth++; //层数+1
}
return depth;
}
}
五、二叉树最小深度
1.递归方式
逐层遍历树的所有节点,并记录从根节点到每个叶子节点的深度,返回其中的最小值。
public class BinaryTree {
public int minDepth(TreeNode root) {
if (root == null) {
return 0;
}
int leftDepth = minDepth(root.left);
int rightDepth = minDepth(root.right);
// 如果左子树或右子树为空,返回不为空的那一侧的深度+1
if (root.left == null || root.right == null) {
return leftDepth + rightDepth + 1;
}
return Math.min(leftDepth, rightDepth) + 1;
}
}
2.迭代方式
BFS 是计算二叉树最小深度的一个有效方法,因为它会在访问到第一个叶子节点时立即返回,这保证了找到的路径是最短的。
import java.util.LinkedList;
import java.util.Queue;
public class BinaryTree {
public int minDepth(TreeNode root) {
if (root == null) {
return 0;
}
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
int depth = 1;
while (!queue.isEmpty()) {
int levelSize = queue.size();
for (int i = 0; i < levelSize; i++) {
TreeNode node = queue.poll();
// 检查是否是叶子节点
if (node.left == null && node.right == null) {
return depth;
}
if (node.left != null) {
queue.offer(node.left);
}
if (node.right != null) {
queue.offer(node.right);
}
}
depth++;
}
return depth;
}
}
二叉树节点类
class TreeNode {
int value;
TreeNode left;
TreeNode right;
TreeNode(int value) {
this.value = value;
left = null;
right = null;
}
}