层次遍历(Level Order Traversal)是二叉树遍历的一种方式,它按照树的层级从上到下、从左到右逐层访问节点。层次遍历通常利用队列来实现,是解决树形数据结构问题的重要方法。本文将讲解层次遍历的基本原理,并提供Java和Python的实现代码。
一、层次遍历的基本原理
1.1 什么是层次遍历?
层次遍历是从二叉树的根节点开始,按层级依次访问每一层的所有节点。对于每一层,先访问左子节点,再访问右子节点。
1.2 层次遍历的步骤
- 将根节点加入队列。
- 当队列不为空时:
- 从队列中取出一个节点。
- 访问该节点。
- 将该节点的左子节点加入队列(如果存在)。
- 将该节点的右子节点加入队列(如果存在)。
1.3 示例
给定如下二叉树:
1
/ \
2 3
/ \ \
4 5 6
层次遍历顺序:1 -> 2 -> 3 -> 4 -> 5 -> 6
二、层次遍历的代码实现
2.1 Java实现
节点定义
class TreeNode {
int val;
TreeNode left, right;
TreeNode(int val) {
this.val = val;
}
}
层次遍历方法
import java.util.LinkedList;
import java.util.Queue;
public class LevelOrderTraversal {
public static void levelOrder(TreeNode root) {
if (root == null) {
return;
}
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
while (!queue.isEmpty()) {
TreeNode current = queue.poll(); // 从队列中取出节点
System.out.print(current.val + " "); // 访问节点
if (current.left != null) {
queue.add(current.left); // 将左子节点加入队列
}
if (current.right != null) {
queue.add(current.right); // 将右子节点加入队列
}
}
}
public static void main(String[] args) {
TreeNode root = new TreeNode(1);
root.left = new TreeNode(2);
root.right = new TreeNode(3);
root.left.left = new TreeNode(4);
root.left.right = new TreeNode(5);
root.right.right = new TreeNode(6);
System.out.println("层次遍历结果:");
levelOrder(root);
}
}
输出结果:
层次遍历结果:
1 2 3 4 5 6
2.2 Python实现
节点定义
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
层次遍历方法
from collections import deque
def level_order(root):
if not root:
return
queue = deque([root])
while queue:
current = queue.popleft() # 从队列中取出节点
print(current.val, end=" ") # 访问节点
if current.left:
queue.append(current.left) # 左子节点入队
if current.right:
queue.append(current.right) # 右子节点入队
# 构建示例二叉树
root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)
root.left.left = TreeNode(4)
root.left.right = TreeNode(5)
root.right.right = TreeNode(6)
print("层次遍历结果:")
level_order(root)
输出结果:
层次遍历结果:
1 2 3 4 5 6
三、按层分组的层次遍历
在实际应用中,通常需要将层次遍历的结果按层分组。
3.1 示例输出
层次分组遍历结果:
[[1], [2, 3], [4, 5, 6]]
3.2 Java实现
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
public class LevelOrderByLayer {
public static List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> result = new ArrayList<>();
if (root == null) {
return result;
}
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
while (!queue.isEmpty()) {
int levelSize = queue.size();
List<Integer> currentLevel = new ArrayList<>();
for (int i = 0; i < levelSize; i++) {
TreeNode current = queue.poll();
currentLevel.add(current.val);
if (current.left != null) {
queue.add(current.left);
}
if (current.right != null) {
queue.add(current.right);
}
}
result.add(currentLevel);
}
return result;
}
public static void main(String[] args) {
TreeNode root = new TreeNode(1);
root.left = new TreeNode(2);
root.right = new TreeNode(3);
root.left.left = new TreeNode(4);
root.left.right = new TreeNode(5);
root.right.right = new TreeNode(6);
System.out.println("层次分组遍历结果:");
System.out.println(levelOrder(root));
}
}
3.3 Python实现
from collections import deque
def level_order_by_layer(root):
if not root:
return []
result = []
queue = deque([root])
while queue:
level_size = len(queue)
current_level = []
for _ in range(level_size):
current = queue.popleft()
current_level.append(current.val)
if current.left:
queue.append(current.left)
if current.right:
queue.append(current.right)
result.append(current_level)
return result
# 构建示例二叉树
root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)
root.left.left = TreeNode(4)
root.left.right = TreeNode(5)
root.right.right = TreeNode(6)
print("层次分组遍历结果:")
print(level_order_by_layer(root))
输出结果:
层次分组遍历结果:
[[1], [2, 3], [4, 5, 6]]
四、扩展应用
- 寻找二叉树的最大宽度:
- 在每一层找到左右边界,计算宽度。
- Z字形层次遍历:
- 按照从左到右、从右到左的交替顺序访问节点。
- 完全二叉树判断:
- 层次遍历过程中,验证是否存在空节点且后续节点非空。
五、总结
层次遍历是二叉树操作的基础,利用队列实现逻辑简单高效。通过本文,你已经掌握了:
- 基本的层次遍历实现。
- 按层分组遍历的扩展。
- 常见的实用扩展功能。
层次遍历是解决树形结构问题的重要工具,建议多加练习以熟悉其实现细节和应用场景。