蓝桥杯 历届试题 横向打印二叉树(java)


 问题描述:

二叉树可以用于排序。其原理很简单:对于一个排序二叉树添加新节点时,先与根节点比较,若小则交给左子树继续处理,否则交给右子树。

当遇到空子树时,则把该节点放入那个位置。

比如,10 8 5 7 12 4 的输入顺序,应该建成二叉树如下图所示,其中.表示空白。

...|-12
10-|
...|-8-|
.......|...|-7
.......|-5-|
...........|-4
 
 
本题目要求:根据已知的数字,建立排序二叉树,并在标准输出中横向打印该二叉树。
 
输入格式

输入数据为一行空格分开的N个整数。 N<100,每个数字不超过10000。

输入数据中没有重复的数字。

输出格式

输出该排序二叉树的横向表示。为了便于评卷程序比对空格的数目,请把空格用句点代替


 样例输入1

10 5 20

样例输出1
...|-20
10-|
...|-5
 
样例输入2
5 10 20 8 4 7
 
样例输出2
.......|-20
..|-10-|
..|....|-8-|
..|........|-7
5-|
..|-4

 解题思路:
这个题重要的是横向的输出这个排序二叉树
1.生成排序二叉树,left表示左子树的节点,right表示右子树的节点。
2.通过一个(右根左)的遍历,遍历的输出顺序(depth)就是他们的节点在第几行。
 为后续填写‘|’字符,好知道填写第几行到第几行
3.从root根节点开始,通过一个dfs遍历二叉树所有的节点,同时填写map数组中的相应的字符。
   注意数字一位一个字符,8输出占1位,123输出占3位。 

 代码:
import java.util.Scanner;

public class Main {
    static int maxn = 10001;
    static int t;
    static int height;
    static char[][] map = new char[100][400];
    static int[] left = new int[maxn];//i的左子树left[i]
    static int[] right = new int[maxn];//i的右子树right[i]
    static int depth[] = new int[maxn];//i在第depth[i]行
    static int len[] = new int[100];
    //排序二叉树中加入节点
    public static void add(int r,int m) {
        if(m<r) {
            if(left[r]==0)
                left[r] = m;
            else
                add(left[r],m);
        }
        else {
            if(right[r]==0)
                right[r] = m;
            else
                add(right[r],m);
        }
    }
    //获取节点的数在第几行
    public static void tra(int r) {
        if(right[r]!=0) 
            tra(right[r]);
        depth[r] = ++t;
        if(left[r]!=0)
            tra(left[r]);
    }
    public static void printTree() {
        for(int i=1;i<=height;i++) {
            for(int j=1;j<len[i];j++) {
                System.out.print(map[i][j]);
            }
            System.out.println();
        }
    }
    //遍历二叉树同时横向填写map数组
    public static void dfsTree(int r,int xi,int xj) {
        String ri = Integer.toString(r);
        for(int i=0;i<ri.length();i++) {
            map[xi][xj++] = ri.charAt(i);
        }
        //len表示这一行的字符长度
        if(left[r]==0 && right[r]==0)//叶子节点
            len[xi] = xj;
        else
            len[xi] = xj+2;
        
        if(right[r]!=0) {
            map[xi][xj] = '-';
            int lr = right[r];
            for(int i=xi;i>=depth[lr];i--) {
                map[i][xj+1] = '|';
            }
            map[depth[lr]][xj+2] = '-';
            dfsTree(lr,depth[lr],xj+3);
        }
        if(left[r]!=0) {
            map[xi][xj] = '-';
            int ll = left[r];
            for(int i=depth[ll];i>=xi;i--)
                map[i][xj+1] = '|';
            map[depth[ll]][xj+2] = '-';
            dfsTree(ll,depth[ll],xj+3);
        }
    }
    public static void main(String[] args) {
        //初始化map数组
        for(int i=1;i<100;i++)
            for(int j=1;j<400;j++)
                map[i][j] = '.';

        Scanner cin = new Scanner(System.in);
        String s = cin.nextLine();
        String[] ss = s.split(" ");
        int root = Integer.parseInt(ss[0]);
        height = ss.length;//有多少个数字
        for(int i=1;i<ss.length;i++) {
            int num = Integer.parseInt(ss[i]);
            add(root,num);
        }
        tra(root);//得所有节点的深度depth
        dfsTree(root,depth[root],1);
        printTree();//横向输出这个树
    }
}

  

 样例1

 

 样例2

 

 样例3

 


这道题提交不知道为啥一直运行错误,刚开始一直找错误,后来索性直接来个输入,随便输出些,结果还是运行错误。。。后来没办法,找了别人博客的好几个代码,提交结果都是运行错误,可能是评测系统有问题???
_(:ι」∠)_要是有大佬搞出来了麻烦指出

 

 

posted @ 2020-05-04 18:40  吐司奶猫荷包蛋  阅读(367)  评论(0)    收藏  举报