剑指offer刷题打印树系列

Posted 王六六的IT日常

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指offer刷题打印树系列相关的知识,希望对你有一定的参考价值。

好久没在这个博客写文章了,最近都住在语雀哈哈哈

面试题32 - I. 从上到下打印二叉树 = 不分行从上往下打印二叉树

题目描述:
从上往下打印出二叉树的每个结点,同一层的结点按照从左到右的顺序打印。
思路:
输入为根节点,返回值类型为数组:队列存树节点,先将树的结点值存在列表->数组

Java List.get(index)方法:获取列表下标为index的元素
Java List.size()方法:返回列表中元素的个数

//树的定义
public class TreeNode 
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x)  val = x; 


class Solution 
    public int[] levelOrder(TreeNode root) 

        //根节点为空返回空数组
        if(root == null)
            return new int[0];
        
        //定义保存树节点的列表,先将根节点加入队列
        Queue<TreeNode> q = new LinkedList<>();
        q.add(root);
        //Queue<TreeNode> queue = new LinkedList<>() add(root); ;

        //定义保存节点值的列表
        List<Integer> ans = new ArrayList<>();
        //队列不为空,则出队一个元素并且将该元素值加入队列中,再判断该节点的左右子节点
        while(!q.isEmpty())
            TreeNode cur = q.poll();
            ans.add(cur.val);

            if(cur.left != null)
                q.add(cur.left);
            
            if(cur.right != null)
                q.add(cur.right);
            
        
        //定义最后的结果数组,将列表中的元素转移到数组中
        int[] res = new int[ans.size()];
        for(int i=0;i<ans.size();i++)
            res[i] = ans.get(i);
        
        return res;
    

返回值类型为列表:列表存节点值,队列存树节点

class Solution 
    public List<Integer> printFromTopToBottom(TreeNode root) 
        List<Integer> list = new ArrayList<>();
        //如果根节点为空返回一个空的list
        if(root == null)
            return list;
        
        
        //根节点不为空,定义一个队列
        Queue<TreeNode> q = new LinkedList<>();
        
        //将根节点加入队列
        q.add(root);

        while(!q.isEmpty())
            //队列不空,取出队列的头节点, poll:移除并返问队列头部的元素
            TreeNode node = q.poll();
            //当前节点添加到列表里
            list.add(node.val);
            //按顺序扩展,先左后右
            if(node.left != null)
                q.add(node.left);
            
            if(node.right != null)
                q.add(node.right);
            
        
        return list;
    

剑指 Offer 32 - II. 从上到下打印二叉树 II == 分行从上往下打印二叉树

题目描述:
从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。
思路:
输入类型为根节点TreeNode root,返回类型为列表集合List<List>。
队列存树节点。
levelList是res这个列表集合的一个列表,levelList对level集合保持引用关系,如果level改变,res集合里面的每一个都会对应改变。

class Solution 
    public List<List<Integer>> printFromTopToBottom(TreeNode root) 
        
        //定义返回集合
        List<List<Integer>> res = new ArrayList<>();
        
        //采用宽度遍历,装元素的队列q
        Queue<TreeNode> q = new LinkedList<>();
        
        //初始化一个装 一层 元素的集合
        List<Integer> level = new ArrayList<>();
        
        if(root == null)
            return res;
        
        
        q.add(root);
        //采用加入null,来标志本层元素已经遍历完
        q.add(null);
        
        while(!q.isEmpty())
            //队头元素出队
            TreeNode node = q.poll();

            //如果出队的队头元素为null,说明遍历了一整行
            if(node == null)
                //list是res这个集合的一个集合元素 , 对level集合保持引用关系
                //如果level改变,res集合里面的每一个都会对应改变
                List<Integer> levelList = new ArrayList<>(level);
                //把level(list)放到返回结果里
                res.add(levelList);
                
                //清除level,为了下一层元素进入
                level.clear();
                
                if(q.isEmpty())
                    break;
                else
                    //加入null,来标志本层元素已经遍历完
                    q.add(null);
                    //直接进入下一次循环
                    continue;
                
            
            
            //当前节点添加到level集合中
            level.add(node.val);
            
            //按顺序扩展,先左后右
            if(node.left!=null)
                q.add(node.left);
            
            if(node.right!=null)
                q.add(node.right);
            
            
        
        return res;
    

剑指 Offer 32 - III. 从上到下打印二叉树 III = 之字形打印二叉树

题目描述:
请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。
输入类型为根节点TreeNode root,返回类型为列表集合List<List>。

思路:
加入标志:

  • true:从左往右
  • false:从右往左

从右往左打印:一直往前面插入来实现:list.add(0,cur.val);

class Solution 
    public List<List<Integer>> levelOrder(TreeNode root) 
        List<List<Integer>> res = new ArrayList<>();
        if(root == null)
            return res;
        
        Queue<TreeNode> q = new LinkedList<>();
        q.add(root);

        //true:从左往右
        //false:从右往左
        boolean flag = true;

        while(!q.isEmpty())
            int n = q.size();
            List<Integer> list = new ArrayList<>();
            for(int i=0;i<n;i++)
                TreeNode cur = q.poll();
                if(flag)//从左往右
                    list.add(cur.val);
                else//从指定位置插入元素值,然后一直被前插,从右往左
                    list.add(0,cur.val);
                
                //判断该节点的左右节点是否存在
                if(node.left!=null)
                    q.add(node.left);
                
                if(node.right!=null)
                    q.add(node.right);
                

            
            //标志改变
            flag = !flag;
            res.add(list);
        
        return res;
    

以上是关于剑指offer刷题打印树系列的主要内容,如果未能解决你的问题,请参考以下文章

剑指Offer对答如流系列 - 从上往下打印二叉树

《剑指offer刷题笔记》31不分行从上往下打印二叉树c++详细题解

剑指offer-面试题32-分行从上到下打印二叉树-二叉树遍历

剑指Offer刷题 把二叉树打印成多行

剑指offer系列刷题第二篇——从尾到头打印链表和反转链表

《剑指 Offer(第 2 版)》系列刷题