横着打印二叉树的形状,形状真的和二叉树一样,而不是遍历二叉树

横着打印二叉树的形状,形状真的和二叉树一样,而不是遍历二叉树

提示:这是比较基础的一个递归方法


题目

横着打印二叉树的形状,形状真的和二叉树一样,而不是遍历二叉树


一、审题

示例:下列二叉树
在这里插入图片描述
横着打印二叉树的形状:
输出板上是这样的:

             R3R    
                       L4L    
   H1H    
             L2L

在这里插入图片描述
本题的节点和树:

public static class Node{
        public int value;
        public Node left;
        public Node right;
        public Node(int v){
            value = v;
        }
    }

    //构造一颗树,今后方便使用
    public static Node generateBinaryTree(){
        //树长啥样呢
        //          1
        //        2    3
        //      4  5  6  7
        //        8    9
        Node head = new Node(1);
        Node n2 = new Node(2);
        Node n3 = new Node(3);
        head.left = n2;
        head.right = n3;
        Node n4 = new Node(4);
        Node n5 = new Node(5);
        n2.left = n4;
        n2.right = n5;
        Node n6 = new Node(6);
        Node n7 = new Node(7);
        n3.left = n6;
        n3.right = n7;
        Node n8 = new Node(8);
        Node n9 = new Node(9);
        n5.left = n8;
        n6.right = n9;
        return head;
    }

二、解题

实际上你也看到了,这是一个横着打印的二叉树的形状,而不是遍历打印数字
本质上,从输出板上到下,应该先输出二叉树的右树,再输出头节点,再输出二叉树的左树

不妨设2层之间的高度差为N=10
在这里插入图片描述

则随着0层开始,每增加一层来到k层,咱需要在打印节点之前,先打印k*N个空格!

打印一个节点,也让要打印的定长为N=10
为了做表示,咱们在右树上做R标记,左树做L标记,比如:
3节点:val = R3R
2节点:val = L2L
那每个节点中间的长度lenM=len(val)
节点左边要补lenL=N-lenM/2这么长
所以右边补lenR=N-lenL-lenM这么长
在这里插入图片描述
然后手撕代码打印即可:
每次先打印右树:
再打印头节点
最后打印左树
——右头左的遍历顺序

这里要注意的是:当你同时生成N个空格时,需要java中的StringBuffer 类实现

//复习,生成空格:
    public static String getSpaceReview(int N){
        if (N == 0) return "";

        String ans = "";
        StringBuffer tmp = new StringBuffer();
        for (int i = 0; i < N; i++) {
            tmp.append(" ");//N个空格
        }

        return ans + tmp;
    }

然后就是手撕:遍历生成树的形状代码:

//从head的0层开始,打印val,它的标记是L/R,每次打印固定长度N
    public static void basePrint(Node head, int height, String flag, int N){
        if (head == null) return;//叶节点的null不打印

        //右头左
        basePrint(head.right, height + 1, "R", N);

        String value = flag + String.valueOf(head.value) + flag;//拼标志
        int lenM = value.length();
        int lenL = (N - lenM) >> 1;//左右补空格
        int lenR = N - lenL - lenM;
        String outValue = getSpaceReview(lenL) + value + getSpaceReview(lenR);//补全
        System.out.println(getSpaceReview(height * N) + outValue);//每层高左边还要顶这么多空格

        //左树
        basePrint(head.left, height + 1, "L", N);
    }
    //正规从头节点开始打印
    public static void shapeBTPrint(Node head){
        if (head == null) return;

        basePrint(head, 0, "H", 10);
        //从0层的头节点开始打印,头节点的标记是H,代表head,固定输出长度为N=10,层增加一层顶N空格
    }

    public static void test2(){
        Node head = generateBinaryTree();
        shapeBTPrint(head);
    }

    public static void main(String[] args) {
//        test();
        test2();
    }

看看结果:

                       R7R    
             R3R    
                                 R9R    
                       L6L    
   H1H    
                       R5R    
                                 L8L    
             L2L    
                       L4L    


总结

提示:重要经验:

1)基础打印形状这个,主要就是定长打印N,不空格,然后层之间的高度差为N,然后遍历顺序是右头左的顺序
2)打印一串空格,完全可以用Java中的StringBuffer类搞定,append函数熟悉一下
3)笔试求AC,可以不考虑空间复杂度,但是面试既要考虑时间复杂度最优,也要考虑空间复杂度最优。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冰露可乐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值