剑指offer面试题32:从上到下打印二叉树(Java 实现)

本文深入探讨了三种不同的二叉树打印算法:按层遍历、分行打印及之字形打印。通过队列和双栈技巧,文章详细解析了每种算法的实现过程,并提供了完整的Java代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:从上往下打印出二叉树的每个节点,同层节点从左至右打印。

思路:此题实际考察树的按层遍历的算法,利用一个队列来实现。

首先打印树的根节点,然后判断这个节点是否有子节点,若有子节点就把它们放入队列中。接下来每次从队列中取出并打印一个节点,同时判断它有没有子节点,若有子节点同样地放入队列中,最后当队列空了,树的节点也就打印完了。

测试用例:

  1. 功能测试:完全二叉树;所有节点只有左子树的二叉树;所有节点只有右子树的二叉树。
  2. 特殊测试:输入的根节点为空;二叉树只有一个节点。
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;

public class test_thirty_two {
    public ArrayList<Integer> printFromTopToBottom(TreeNode root){
        ArrayList<Integer> list = new ArrayList<>();
        Queue<TreeNode> queue = new LinkedList<>();

        if(root == null)return list;

        queue.offer(root);
        while (!queue.isEmpty()){
            TreeNode treeNode = queue.poll();
            list.add(treeNode.val);
            if (treeNode.left != null){
                queue.offer(treeNode.left);
            }
            if (treeNode.right != null){
                queue.offer(treeNode.right);
            }
        }
        return list;
    }
}

题目二:分行从上到下打印二叉树
 

 //分行打印二叉树
    public ArrayList<ArrayList<Integer>> printFromTopToBottom1(TreeNode root){
        ArrayList<Integer> lineList = new ArrayList<>();    //容器中的一行
        Queue<TreeNode> queue = new LinkedList<>();
        ArrayList<ArrayList<Integer>> list = new ArrayList<>();    //整一个数组容器

        if(root == null)return list;

        int toBePrinted = 1;     //定义这一行还未打印的个数
        int nextLine = 0;        //定义下一个要打印的个数

        queue.offer(root);
        while (!queue.isEmpty()){
            TreeNode treeNode = queue.poll();
            lineList.add(treeNode.val);
            toBePrinted--;                   //当前行每打印一个元素
            if (treeNode.left != null){
                queue.offer(treeNode.left);
                nextLine++;                  //队列中每添加一个元素
            }
            if (treeNode.right != null){
                queue.offer(treeNode.right);
                nextLine++;                  //队列中每添加一个元素
            }
            if (toBePrinted == 0){           //当前行打印完了
               list.add(lineList);           //把每一行放进整一个容器中
               lineList = new ArrayList<>();
               toBePrinted = nextLine;       //接着打印下一行
               nextLine = 0;
            }
        }
        return list;
    }

题目三:之字形从上到下打印二叉树。

思路:定义两个栈来分别存储奇数层和偶数层中的节点,奇数层的节点左节点先入栈,偶数层的节点右节点先入栈。

//之字形从上到下打印二叉树
    public ArrayList<ArrayList<Integer>> print(TreeNode pRoot){
        ArrayList<ArrayList<Integer>> list = new ArrayList<ArrayList<Integer>>();
        Stack<TreeNode> stack1 = new Stack<>();  //存储奇数层的节点
        Stack<TreeNode> stack2 = new Stack<>();  //存储偶数层的节点

        if (pRoot == null)return list;

        int layer = 1;        //用来表示层数
        stack1.push(pRoot);   //开始把根节点压入栈中(第一层)

        while (!stack1.isEmpty() || !stack2.isEmpty()){
            if (layer%2 != 0){        //层数为奇数
                //定义一个临时的数组容器来这一层的元素
                ArrayList<Integer> temp = new ArrayList<>();
               while (!stack1.isEmpty()){
                   TreeNode treeNode = stack1.pop();
                   if (treeNode != null){
                       temp.add(treeNode.val);
                       System.out.println(treeNode.val+" ");
                   }
                   //子节点在偶数层中,用第二个栈来存储(右节点先入栈)
                   if (treeNode.left != null)stack2.push(treeNode.left);
                   if (treeNode.right != null)stack2.push(treeNode.right);
               }
               if (!temp.isEmpty()){
                   list.add(temp);
                   layer++;
                   System.out.println();
               }
            }else {          //层数为偶数
                //定义一个临时的数组容器来这一层的元素
                ArrayList<Integer> temp = new ArrayList<>();
                while (!stack2.isEmpty()){
                    TreeNode treeNode = stack2.pop();
                    if (treeNode != null){
                        temp.add(treeNode.val);
                        System.out.println(treeNode.val+" ");
                    }
                    //子节点在奇数层中,用第一栈来存储
                    if (treeNode.right != null)stack1.push(treeNode.right);
                    if (treeNode.left != null)stack1.push(treeNode.left);
                }
               if (!temp.isEmpty()){
                    list.add(temp);
                    layer++;
                    System.out.println();
                }
            }
        }
        return list;
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值