面试经典算法18 - 二叉树的层序遍历
LeetCode.102
 公众号:阿Q技术站
问题描述
给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。
示例 1:

输入:root = [3,9,20,null,null,15,7]
输出:[[3],[9,20],[15,7]]
示例 2:
输入:root = [1]
输出:[[1]]
示例 3:
输入:root = []
输出:[]
提示:
- 树中节点数目在范围 [0, 2000]内
- -1000 <= Node.val <= 1000
思路
递归
- 定义一个辅助函数 levelOrderHelper,用来递归遍历二叉树的每一层,并将节点值按层级存储在result中。
- 辅助函数的参数包括当前节点 root、当前层级level和存储结果的二维数组result。
- 如果当前节点为空,则直接返回。
- 如果当前层级大于等于 result的大小,说明需要添加新的一层,因为层序遍历是逐层遍历的。
- 将当前节点的值加入到 result的对应层级中。
- 递归遍历当前节点的左子树,层级加一。
- 递归遍历当前节点的右子树,层级加一。
- 主函数 levelOrder中调用辅助函数levelOrderHelper开始遍历整棵树。
- 最后返回存储结果的二维数组 result。
非递归
- 创建一个队列 queue和一个存储结果的二维数组result。
- 将根节点入队。
- 循环直到队列为空: 
  - 从队列中取出一个节点,将其值存储到当前层级的结果数组中。
- 如果节点有左子节点,则将左子节点入队。
- 如果节点有右子节点,则将右子节点入队。
 
- 将当前层级的结果数组加入到最终的结果中。
- 继续循环直到队列为空,完成整个二叉树的层序遍历。
图解
- 创建一个队列 queue和一个存储结果的二维数组result,将根节点入队。

- 队列不为空时,新建一个空数组level,用于存储当前层级节点值,然后进行循环打印,循环次数为当前层的节点数,也就是队列的长度。

- 将队头元素弹出,存入当前层级的数组中。

- 接着将当前节点的左右节点依次入队(如果有),然后将当前层级的节点值数组加入结果中。

- 继续第3步。

- 继续第4步。

- 继续第3步。

- 继续第4步。

此时,队列为空,退出循环,返回结果集。
参考代码
C++
递归
#include <iostream>
#include <vector>
using namespace std;
// 二叉树节点的定义
struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
// 辅助函数,递归实现层序遍历
void levelOrderHelper(TreeNode* root, int level, vector<vector<int>>& result) {
    if (!root) return;
    
    if (level >= result.size()) {
        result.push_back({});
    }
    
    result[level].push_back(root->val);
    
    levelOrderHelper(root->left, level + 1, result);
    levelOrderHelper(root->right, level + 1, result);
}
// 主函数,返回二叉树的层序遍历结果
vector<vector<int>> levelOrder(TreeNode* root) {
    vector<vector<int>> result;
    levelOrderHelper(root, 0, result);
    return result;
}
// 创建二叉树
TreeNode* createTree(vector<int>& nodes, int index) {
    if (index >= nodes.size() || nodes[index] == -1) {
        return nullptr; // 如果节点为空,则返回nullptr
    }
    TreeNode* root = new TreeNode(nodes[index]); // 创建当前节点
    root->left = createTree(nodes, 2 * index + 1); // 创建左子树
    root->right = createTree(nodes, 2 * index + 2); // 创建右子树
    return root; // 返回当前节点
}
// 销毁二叉树
void destroyTree(TreeNode* root) {
    if (!root) return; // 如果根节点为空,直接返回
    destroyTree(root->left); // 递归销毁左子树
    destroyTree(root->right); // 递归销毁右子树
    delete root; // 删除当前节点
}
int main() {
    // 输入数据,示例二叉树为 {3,9,20,#,#,15,7}
    vector<int> nodes = {3, 9, 20, -1, -1, 15, 7};
    TreeNode* root = createTree(nodes, 0); // 创建二叉树
    // 调用层序遍历函数
    vector<vector<int>> result = levelOrder(root);
    // 输出遍历结果
    for (vector<int> level : result) {
        for (int val : level) {
            cout << val << " ";
        }
        cout << endl;
    }
    // 销毁二叉树
    destroyTree(root);
    return 0;
}
非递归
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
// 二叉树节点的定义
struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
vector<vector<int>> levelOrder(TreeNode* root) {
    vector<vector<int>> result; // 存储结果的二维数组
    if (!root) return result; // 如果根节点为空,直接返回空结果数组
    queue<TreeNode*> q; // 辅助队列,用于层序遍历
    q.push(root); // 将根节点入队
    while (!q.empty()) {
        int size = q.size(); // 当前层级的节点数
        vector<int> level; // 存储当前层级节点值的数组
        for (int i = 0; i < size; i++) {
            TreeNode* node = q.front(); // 获取队头节点
            q.pop(); // 弹出队头节点
            level.push_back(node->val); // 将节点值加入当前层级的数组中
            if (node->left) q.push(node->left); // 将左子节点入队
            if (node->right) q.push(node->right); // 将右子节点入队
        }
        result.push_back(level); // 将当前层级的节点值数组加入结果中
    }
    return result; // 返回层序遍历的结果数组
}
// 创建二叉树
TreeNode* createTree(vector<int>& nodes, int index) {
    if (index >= nodes.size() || nodes[index] == -1) {
        return nullptr; // 如果节点为空,则返回nullptr
    }
    TreeNode* root = new TreeNode(nodes[index]); // 创建当前节点
    root->left = createTree(nodes, 2 * index + 1); // 创建左子树
    root->right = createTree(nodes, 2 * index + 2); // 创建右子树
    return root; // 返回当前节点
}
// 销毁二叉树
void destroyTree(TreeNode* root) {
    if (!root) return; // 如果根节点为空,直接返回
    destroyTree(root->left); // 递归销毁左子树
    destroyTree(root->right); // 递归销毁右子树
    delete root; // 删除当前节点
}
int main() {
    vector<int> nodes = {3, 9, 20, -1, -1, 15, 7}; // 二叉树的层序遍历序列
    TreeNode* root = createTree(nodes, 0); // 创建二叉树
    vector<vector<int>> result = levelOrder(root); // 进行层序遍历
    for (auto& level : result) { // 输出遍历结果
        for (int val : level) {
            cout << val << " ";
        }
        cout << endl;
    }
    destroyTree(root); // 销毁二叉树
    return 0;
}
Java
import java.util.*;
// 二叉树节点的定义
class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) { val = x; }
}
public class Main {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> result = new ArrayList<>(); // 存储结果的二维数组
        if (root == null) return result; // 如果根节点为空,直接返回空结果数组
        Queue<TreeNode> queue = new LinkedList<>(); // 辅助队列,用于层序遍历
        queue.offer(root); // 将根节点入队
        while (!queue.isEmpty()) {
            int size = queue.size(); // 当前层级的节点数
            List<Integer> level = new ArrayList<>(); // 存储当前层级节点值的数组
            for (int i = 0; i < size; i++) {
                TreeNode node = queue.poll(); // 获取队头节点
                level.add(node.val); // 将节点值加入当前层级的数组中
                if (node.left != null) queue.offer(node.left); // 将左子节点入队
                if (node.right != null) queue.offer(node.right); // 将右子节点入队
            }
            result.add(level); // 将当前层级的节点值数组加入结果中
        }
        return result; // 返回层序遍历的结果数组
    }
    // 创建二叉树
    public TreeNode createTree(Integer[] nodes, int index) {
        if (index >= nodes.length || nodes[index] == null) {
            return null; // 如果节点为空,则返回null
        }
        TreeNode root = new TreeNode(nodes[index]); // 创建当前节点
        root.left = createTree(nodes, 2 * index + 1); // 创建左子树
        root.right = createTree(nodes, 2 * index + 2); // 创建右子树
        return root; // 返回当前节点
    }
    // 销毁二叉树
    public void destroyTree(TreeNode root) {
        if (root == null) return; // 如果根节点为空,直接返回
        destroyTree(root.left); // 递归销毁左子树
        destroyTree(root.right); // 递归销毁右子树
        root = null; // 将当前节点置为null
    }
    public static void main(String[] args) {
        Integer[] nodes = {3, 9, 20, null, null, 15, 7}; // 二叉树的层序遍历序列
        Main main = new Main();
        TreeNode root = main.createTree(nodes, 0); // 创建二叉树
        List<List<Integer>> result = main.levelOrder(root); // 进行层序遍历
        for (List<Integer> level : result) { // 输出遍历结果
            for (int val : level) {
                System.out.print(val + " ");
            }
            System.out.println();
        }
        main.destroyTree(root); // 销毁二叉树
    }
}
Python
from typing import List
from collections import deque
# 二叉树节点的定义
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
def levelOrder(root: TreeNode) -> List[List[int]]:
    result = [] # 存储结果的二维数组
    if not root:
        return result # 如果根节点为空,直接返回空结果数组
    queue = deque([root]) # 辅助队列,用于层序遍历
    while queue:
        level_size = len(queue) # 当前层级的节点数
        level = [] # 存储当前层级节点值的数组
        for _ in range(level_size):
            node = queue.popleft() # 获取队头节点
            level.append(node.val) # 将节点值加入当前层级的数组中
            if node.left:
                queue.append(node.left) # 将左子节点入队
            if node.right:
                queue.append(node.right) # 将右子节点入队
        result.append(level) # 将当前层级的节点值数组加入结果中
    return result # 返回层序遍历的结果数组
# 创建二叉树
def createTree(nodes: List[int], index: int) -> TreeNode:
    if index >= len(nodes) or nodes[index] is None:
        return None # 如果节点为空,则返回None
    root = TreeNode(nodes[index]) # 创建当前节点
    root.left = createTree(nodes, 2 * index + 1) # 创建左子树
    root.right = createTree(nodes, 2 * index + 2) # 创建右子树
    return root # 返回当前节点
# 销毁二叉树
def destroyTree(root: TreeNode) -> None:
    if not root:
        return # 如果根节点为空,直接返回
    destroyTree(root.left) # 递归销毁左子树
    destroyTree(root.right) # 递归销毁右子树
    root = None # 将当前节点置为None
# 测试代码
nodes = [3, 9, 20, None, None, 15, 7] # 二叉树的层序遍历序列
root = createTree(nodes, 0) # 创建二叉树
result = levelOrder(root) # 进行层序遍历
for level in result: # 输出遍历结果
    print(level)
destroyTree(root) # 销毁二叉树



















