day27 JZ32 从上往下打印二叉树(Java)

107 阅读1分钟

题目来源: JZ32 从上往下打印二叉树

题目描述:

  • 描述: 不分行从上往下打印出二叉树的每个节点,同层节点从左至右打印。例如输入{8,6,10,#,#,2,1},如以下图中的示例二叉树,则依次打印8,6,10,2,1(空节点不打印,跳过),请你将打印的结果存放到一个数组里面,返回。
    • 6C502E0240CAC668843969AFF396B5E4.png 数据范围: 0<=节点总数<=1000;-1000<=节点值<=1000
示例1:
输入:{8,6,10,#,#,2,1}
返回值:[8,6,10,2,1]

示例2:
输入:[8,6,10,2,1]
输出:[5,4,3,2,1]      

思路:队列

  • 知识点:队列
    • 队列是一种线性表,它的插入操作仅支持在表尾操作、删除操作仅支持在表头进行操作,而与之相对应的是,插入端称作"队尾",删除端称作"队首",它的特点就是先进先出,就是新元素插入到队列的尾端,就是将队列中的元素从队头取出,该元素的后一个元素为新的队头.
  • 思路:
    • 1.题目的要求是从上往下打印,很明显这与二叉树的层次遍历是相关的,二叉树的层次遍历:按照二叉树的结构,从上往下对每行依次进行遍历,然后对于每行的元素从左到右依次进行遍历
    • 2.由上面的简单介绍可知,队列是一种先进先出的结构,我们根据它这一特点,与二叉树的层次遍历相配合,按照从左到右访问二叉树的每一行结点时,将每一个访问的结点依次加入队列,而相对应的,在每个节点出队列的时候,再将每一个结点的孩子结点,放入队列中,这样它们的孩子结点也会按照从左到右的次序,依次从队列中取出.
  • 具体做法:
    • 1.首先我们对二叉树进行判断是否是空树,如果是空树,是没有遍历结果的
    • 2.创建一个队列进行辅助操作,将二叉树的根节点放入队列,这边开始进行遍历了
    • 3.每次访问从队列的队头取出的结点,如果该节点仍然有孩子结点,那么将它的孩子结点从队列的队尾中插入
  • 图示: 07986E476EB2CECD3C5F81D0BCADBE12.gif

具体实现:

/**
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

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

    }

}
*/
import java.util.*;
public class Solution {
    public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) {
        ArrayList<Integer> res = new ArrayList();
        if(root == null)
            //如果是空,则直接返回空数组
            return res;
        //队列存储,进行层次遍历
        Queue<TreeNode> q = new ArrayDeque<TreeNode>();
        q.offer(root);
        while(!q.isEmpty()){
            TreeNode cur = q.poll();
            res.add(cur.val);
            //若是左右孩子存在,则存入左右孩子作为下一个层次
            if(cur.left != null)
                q.add(cur.left);
            if(cur.right != null)
                q.add(cur.right);
        }
        return res;
    }
}
  • 复杂度分析:
    • 时间复杂度O(n),其中n为二叉树的节点数,每个节点访问一次
    • 空间复杂度O(n),队列的空间为二叉树的一层的节点数,最坏情况二叉树的一层为O(n)级

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 3 天,点击查看活动详情