算法小知识-------02·17-------二叉树的层序遍历

105 阅读2分钟

这是我参与2022首次更文挑战的第25天,活动详情查看:2022首次更文挑战

二叉树的遍历从来都是高频题型,从深度遍历的前序 + 中序 + 后序 遍历二叉树,到广度的层序遍历;简单来说,层序遍历就是把二叉树分层,然后每一层从左到右遍历。并且拓展出递归算法和非递归;再从性能安全的角度,分析递归的压栈导致栈溢出问题;采用非递归实现。

二叉树的层序遍历

该题出自力扣的102题 —— 二叉树的层序遍历【中等题】

审题

给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。

  • 该题题意十分明了,就是层序遍历
  • 需要借用一个辅助数据结构即队列来实现,队列先进先出,符合一层一层遍历的逻辑,而是用栈先进后出适合模拟深度优先遍历也就是递归的逻辑。
  • 使用队列实现二叉树广度优先遍历
  • 但是之所以是中等题,应该就是需要返回List<List>,也就是需要分析出同一层的节点
  • 解题
    • 判断当前节点是否为空
    • 利用队列去实现非递归的层序遍历
      • 节点进队列
      • 弹出队列头部节点
      • 节点左右子节点进队列
    • 判断是否为同一层的节点
      • 定义变量count,当前队列的长度
      • 每次新增队列操作后,count--
    • 时间复杂度O(n),每个节点进队列 + 出队列 为O(n)
    • 空间复杂度O(n),创建一个长度为n的队列

编码

  public class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode() {}
    TreeNode(int val) { this.val = val; }
    TreeNode(int val, TreeNode left, TreeNode right) {
        this.val = val;
        this.left = left;
        this.right = right;
    }
}
    public List<List<Integer>> levelOrder(TreeNode root) {
        if (root == null)return new ArrayList<>();
        List<List<Integer>> lists = new ArrayList<>();
        Queue<TreeNode> queue = new LinkedList<>();
        queue.add(root);
        while (!queue.isEmpty()){
            //计算queue的长度
            int count = queue.size();
            List<Integer> list = new ArrayList<>();
            while (count>0){
                TreeNode node = queue.poll();
                list.add(node.val);
                if (node.left != null)queue.add(node.left);
                if (node.right != null)queue.add(node.right);
                count--;
            }
            lists.add(list);
        }
        return lists;
    }

image.png