在 Java 中,循环(遍历)树形结构通常有两种常见的方式:深度优先遍历(DFS, Depth-First Search)和广度优先遍历(BFS, Breadth-First Search)。
树是一种递归结构,每个节点都有可能有多个子节点。常见的树节点结构如下:
class TreeNode {
int value;
List<TreeNode> children;
public TreeNode(int value) {
this.value = value;
this.children = new ArrayList<>();
}
public void addChild(TreeNode child) {
children.add(child);
}
}
接下来分别介绍如何通过 DFS 和 BFS 来遍历这个树形结构。
1. 深度优先遍历(DFS)
递归方式
深度优先遍历可以使用递归来实现。对于每个节点,首先访问它本身,然后递归地访问它的每个子节点。
public void dfs(TreeNode node) {
if (node == null) return;
// 访问当前节点
System.out.println(node.value);
// 递归访问每个子节点
for (TreeNode child : node.children) {
dfs(child);
}
}
示例:
假设有以下树形结构:
1
/ \
2 3
/ \
4 5
代码:
public static void main(String[] args) {
TreeNode root = new TreeNode(1);
TreeNode child1 = new TreeNode(2);
TreeNode child2 = new TreeNode(3);
root.addChild(child1);
root.addChild(child2);
child1.addChild(new TreeNode(4));
child1.addChild(new TreeNode(5));
dfs(root); // 输出: 1 2 4 5 3
}
输出顺序是:1 2 4 5 3
,这就是深度优先遍历的顺序。
非递归方式(使用栈)
除了递归,还可以使用显式的栈来实现 DFS 遍历。
public void dfsIterative(TreeNode root) {
if (root == null) return;
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()) {
TreeNode current = stack.pop();
System.out.println(current.value);
// 将子节点逆序压入栈中,这样可以保持左到右的访问顺序
List<TreeNode> children = current.children;
for (int i = children.size() - 1; i >= 0; i--) {
stack.push(children.get(i));
}
}
}
2. 广度优先遍历(BFS)
广度优先遍历可以使用队列来实现,依次访问每个节点,并将子节点加入队列。
public void bfs(TreeNode root) {
if (root == null) return;
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
while (!queue.isEmpty()) {
TreeNode current = queue.poll();
System.out.println(current.value);
// 将子节点加入队列
for (TreeNode child : current.children) {
queue.add(child);
}
}
}
示例:
同样的树形结构:
1
/ \
2 3
/ \
4 5
public static void main(String[] args) {
TreeNode root = new TreeNode(1);
TreeNode child1 = new TreeNode(2);
TreeNode child2 = new TreeNode(3);
root.addChild(child1);
root.addChild(child2);
child1.addChild(new TreeNode(4));
child1.addChild(new TreeNode(5));
bfs(root); // 输出: 1 2 3 4 5
}
输出顺序是:1 2 3 4 5
,这是广度优先遍历的顺序。
总结
- 深度优先遍历(DFS):可以使用递归或栈来实现,优先深入子节点,再处理兄弟节点。
- 广度优先遍历(BFS):使用队列来实现,优先访问每层的所有节点,然后处理下一层。
根据不同的应用场景,选择不同的遍历方式,例如 DFS 更适合查找路径、求解递归问题,而 BFS 更适合寻找最短路径或分层处理树的结构。