推荐

完整《剑指Offer》算法题解析系列请点击 👉 《剑指Offer》全解析 Java 版

题目描述

请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。

import java.util.ArrayList;

/* public class TreeNode { int val = 0; TreeNode left = null; TreeNode right = null; public TreeNode(int val) { this.val = val; } } */
public class Solution {
   
    public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
   

    }

}

思路: 将二叉树中每行结点都单独存入一个临时集合中,直接从临时集合存入到结果集合中,相当于这行是从左往右打印;将临时集合翻转之后再存入结果集合中,相当于这行是从右往左打印。

  1. 先创建一个集合 result 来存储最终结果
  2. 创建一个 LinkedList 类型的 queue 来存二叉树中每行的结点。(LinkedList 也实现了 Queue 接口,可以使用队列中的方法。)
  3. 先将根结点存入 queue ,并设置一个标记来判断是否需要翻转。
  4. 将 queue 中的结点依次取出存入临时集合 list 并从 queu 中删除,同时将这些结点的子节点存入queue中。
  5. 根据标记来决定是否翻转list
  6. 将 list 中的 数据存入 结果集合result中。
  7. 重复步骤 4 ~ 6 ,直到遍历完二叉树。

实现:

import java.util.ArrayList;
import java.util.*;

/* public class TreeNode { int val = 0; TreeNode left = null; TreeNode right = null; public TreeNode(int val) { this.val = val; } } */
public class Solution {
   
    public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
   
        //创建一个结果数组
        ArrayList<ArrayList<Integer>> result = new ArrayList<>();
        //创建一个LinkedList存储树的结点
        Queue<TreeNode> queue = new LinkedList<>();
        //将根结点存入队列
        queue.add(pRoot);
        //标记是否需要翻转
        boolean reverse = false;
        //当队列不为空时
        while (!queue.isEmpty()) {
   
            ArrayList<Integer> list = new ArrayList<>();
            //队列中结点的数量
            int count = queue.size();
            
            //将当前队列中的所有结点取出存入list,并将这些的结点的子节点存入队列。
            while (count-- > 0){
   
                //取出队列中第一个元素,并在队列中删除这个元素
                TreeNode node = queue.poll();
                if(node == null) {
   
                    continue;
                }
                list.add(node.val);
                queue.add(node.left);
                queue.add(node.right);
            }
            //判断标记是否要翻转,不翻转就是从左到右存入,翻转之后就是从右忘左打印。
            if (reverse) {
   
                Collections.reverse(list);
            }
            //每次都改变一下标记号,从而实现一次从左往右,一次从右往左,交替打印。
            reverse = !reverse;
            if (list.size() != 0) {
   
                result.add(list);
            }
        }
         return result;
    }

}

看完之后,如果还有什么不懂的,可以在评论区留言,会及时回答更新。

这里是猿兄,为你分享程序员的世界。

非常感谢各位大佬们能看到这里,如果觉得文章还不错的话, 求点赞👍 求关注💗 求分享👬求评论📝 这些对猿兄来说真的 非常有用!!!

注: 如果猿兄这篇博客有任何错误和建议,欢迎大家留言,不胜感激!