从上往下打印二叉树

本文介绍了从上往下打印二叉树的算法思路,通过分析示例展示了分层输出的方法,以及二叉树深度计算的递归实现。并提到了非递归方式和其他遍历方式的实现。

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

题目描述

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

例如下图中的二叉树,则依次打印出8、 6、 10、 5、 7、 9、 11。

 二叉树结点的定义如下:

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

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

思路:

这道题实质是在考查树的遍历算法。只是这种遍历不是我们熟悉的前序(根左右)、中序(左根右)、后序(左右根)遍历。

故就需要从树及打印列表分析。分析上图二叉树的层次打印顺序:

通过上图的具体例子的分析,我们可以找到从上到下打印二叉树的规律:每一次打印一个结点的时候,如果该结点有子结点,则把该结点的子结点放到队列的末尾。接下来到队列的头部取出最早进入队列的结点,重复前面的打印操作,直至队列中所有的结点都被打印出来为止。

分层输出的方法:

也可以参考https://mp.youkuaiyun.com/postedit/83020604  ,写成

static public ArrayList<Integer> printFromTopToBottom(TreeNode node){}的形式
    /**
     * depth=3
     * i=1,2,3 的时候,实现分别打印这一层
     * 根节点 pTreeRoot
     */
    static public void printFromTopToBottom(BinaryTreeNode pTreeRoot) {
        if (pTreeRoot == null) {
            return;
        }
        int depth = depth(pTreeRoot);
        for (int i = 1; i <= depth; ++i) {
            levelOrder(pTreeRoot, i);
        }
    }

 

如何打印这一层的具体实现:

static private void levelOrder(BinaryTreeNode pTreeNode, int level) {

        if(pTreeNode == null || level < 1){//code1
            return ;
        }
        if(level == 1){//code 2
            System.out.print(pTreeNode.data+ " ");
            return ;
        }
       /**
        * 分析,当level>=2时候才执行,才会有level-1=1的情况出现
        */
//code3
       //左子树
        levelOrder(pTreeNode.left, level-1);
        //右子树
        levelOrder(pTreeNode.right, level-1);
    }

step 1)在根节点,初始level=1,仅执行code1,输出8,其左右子节点无输出;

step2) level2,始level=2;仅执行code3,于是

levelOrder(8.left, level-1)= levelOrder(6, 1)=6            
levelOrder(8.right, level-1)=levelOrder(10, 1)=10

 仅输出根节点的左右节点;

step3)level=3, ...

二叉树深度计算的递归实现

 /**
     * 计算二叉树深度,例如depth(8)=3;depth(6)=2;
     * depth(5)=1
     * @param pTreeRoot
     * @return
     */
  static   private int depth(BinaryTreeNode pTreeRoot){
        if(pTreeRoot==null){
            return 0;
        }
        int l = depth(pTreeRoot.left);
        int r = depth(pTreeRoot.right);
        if(l > r){
            return l + 1;
        }else{
            return r + 1;
        }
    }

分析,

难点1)二叉树深度计算的递归实现

图形表示:

测试用例 :

import java.util.ArrayList;

public  class printArrayList {


    //层序遍历二叉树递归实现

    /**
     * 计算节点高度,例如depth(8)=3;depth(6)=2;
     * depth(5)=1
     * @param pTreeRoot
     * @return
     */
    static   private int depth(TreeNode pTreeRoot){
        if(pTreeRoot==null){
            return 0;
        }
        int l = depth(pTreeRoot.left);
        int r = depth(pTreeRoot.right);
        if(l > r){
            return l + 1;
        }else{
            return r + 1;
        }
    }

    static private void levelOrder(TreeNode pTreeNode, int level) {
        if(pTreeNode == null || level < 1){
            return ;
        }
        if(level == 1){
            System.out.print(pTreeNode.val+ " ");
            return ;
        }
        /**
         * 分析,当level>=2时候才执行,才会有level-1=1的情况出现
         */
        //左子树
        levelOrder(pTreeNode.left, level-1);
        //右子树
        levelOrder(pTreeNode.right, level-1);
    }

    /**
     * depth=3
     * i=1,2,3 的时候,实现分别打印这一层
     * 根节点 pTreeRoot
     */
    static public ArrayList<Integer> PrintFromTopToBottom(TreeNode node) {
        ArrayList<Integer> list=new ArrayList<>();

        //printFromTopToBottom(node);

        if (node == null) {
            return list;
        }
        int depth = depth(node);
        for (int i = 1; i <= depth; ++i) {
            levelOrder(node, i);
        }return list;
    }

    public static void main(String[] args) {
        TreeNode root=new TreeNode(8);
        root.left = new TreeNode(6);
        root.right = new TreeNode(10);
        root.left.left = new TreeNode(5);
        root.left.right = new TreeNode(7);
        root.right.left = new TreeNode(9);
        root.right.right = new TreeNode(11);

        PrintFromTopToBottom(root.left);

    }
}

 也可以用队列的方式,比较简单。

  static public ArrayList<Integer> PrintFromTopToBottom(TreeNode node) {
  	ArrayList<Integer> list= new ArrayList<>();//需要打印的list数组
  	if(node==null)
  		return list;
  	Queue<TreeNode> queue=new Queue<>();//用一个队列 
  	queue.offer(node);//放入根节点
  	while(!queue.isEmpty()){
  		TreeNode t=queue.poll();//弹出根节点 并赋值给节点t
  		if(t.left!=null){
  			queue.add(t.left);//把根节点的左节点入队
  		}
  		if(t.right!=null){
  			queue.add(t.right);////把根节点的右节点入队
  		}
  		list.add(t.val);//添加当前弹出的根节点的值到list
     }
     return list;        
  }
  

参考:https://blog.youkuaiyun.com/u013132035/article/details/80604718

依然有很多学习与整理的的地方,可参考上面的链接,属于一个比较完整的归纳。例如

1)非递归方式实现;

2)二叉树深度计算的非递归实现;

3)二叉树的前序、中序列、后序遍历的实现与输出结果。

注明:前序遍历的输出结果为:[8, 6, 5, 7, 10, 9, 11]

前序遍历的代码:

 //前序遍历二叉树
    static ArrayList<Integer> list = new ArrayList<Integer>();

   static public ArrayList<Integer> preOrderBinaryTree(BinaryTreeNode pTreeRoot) {
        if (pTreeRoot != null) {
           list.add(pTreeRoot.data); //先根结点
            preOrderBinaryTree(pTreeRoot.left); //再左边节点调用前序遍历
            preOrderBinaryTree(pTreeRoot.right); //再右边节点调用前序遍历
        } else {
            return null;
        }
        return list;

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值