二叉树的层序遍历

165 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第1天,点击查看活动详情

前言

笔者除了大学时期选修过《算法设计与分析》和《数据结构》还是浑浑噩噩度过的(当时觉得和编程没多大关系),其他时间对算法接触也比较少,但是随着开发时间变长对一些底层代码/处理机制有所接触越发觉得算法的重要性,所以决定开始系统的学习(主要是刷力扣上的题目)和整理,也希望还没开始学习的人尽早开始。

系列文章收录《算法》专栏中。

力扣题目链接

问题描述

给你二叉树的根节点 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

剖析

层序遍历的核心点在于需要在遍历某层的时候暂存子节点,遍历到该层的时候需要清理掉,一层一层的遍历把每层放入二元数组里面即可。

所以我们可以使用队列,存放子节点,遍历到该层的时候一个一个弹出,同时把其子节点放入,遍历下一层的时候就已经清除掉了上一层的元素,就这样一层一层往下遍历。

时间复杂度为O(n)每个节点都要弹出一遍;空间复杂度为O(n),如果二叉树为完全平衡二叉树的话设最底层的个数为m那么上面所有层加在一起的个数为m-1,m+m-1=n所以复杂度为O(n)。

代码

package com.study.algorithm.tree;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

/**
 * 二叉树的层序遍历
 * https://leetcode-cn.com/problems/binary-tree-level-order-traversal/
 * <p>
 * 层序遍历的核心点在于需要在遍历某层的时候暂存子节点,遍历到该层的时候需要清理掉,一层一层的遍历把每层放入二元数组里面即可。
 * <p>
 * 所以我们可以使用队列,存放子节点,遍历到该层的时候一个一个弹出,同时把其子节点放入,遍历下一层的时候就已经清除掉了上一层的元素,就这样一层一层往下遍历。
 * <p>
 * 时间复杂度为O(n)每个节点都要弹出一遍;空间复杂度为O(n),如果二叉树为完全平衡二叉树的话设最底层的个数为m那么上面所有层加在一起的个数为m-1,m+m-1=n所以复杂度为O(n)。
 */
public class TreeLevelTraversal {
    static class TreeNode {
        private Integer val;
        private TreeNode left;
        private TreeNode right;

        public TreeNode(int val) {
            this.val = val;
        }
    }

    public static List<List<Integer>> levelTraversal(TreeNode root) {
        List<List<Integer>> result = new ArrayList<>();
        if (root == null) {
            return result;
        }

        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()) {
            List<Integer> level = new ArrayList<>();
            int levelSize = queue.size();
            for (int i = 1; i <= levelSize; i++) {
                TreeNode treenNode = queue.poll();
                level.add(treenNode.val);
                if (treenNode.left != null) {
                    queue.offer(treenNode.left);
                }
                if (treenNode.right != null) {
                    queue.offer(treenNode.right);
                }
            }
            result.add(level);
        }

        return result;
    }

    public static void main(String[] args) {
        TreeNode root = new TreeNode(3);
        root.left = new TreeNode(9);
        root.right = new TreeNode(20);
        root.right.left = new TreeNode(15);
        root.right.right = new TreeNode(7);
        System.out.println(levelTraversal(root));
    }
}