蓝桥杯 历届试题 横向打印二叉树(java)
问题描述:
二叉树可以用于排序。其原理很简单:对于一个排序二叉树添加新节点时,先与根节点比较,若小则交给左子树继续处理,否则交给右子树。
当遇到空子树时,则把该节点放入那个位置。
比如,10 8 5 7 12 4 的输入顺序,应该建成二叉树如下图所示,其中.表示空白。
...|-12
10-|
...|-8-|
.......|...|-7
.......|-5-|
...........|-4
10-|
...|-8-|
.......|...|-7
.......|-5-|
...........|-4
本题目要求:根据已知的数字,建立排序二叉树,并在标准输出中横向打印该二叉树。
输入格式
输入数据为一行空格分开的N个整数。 N<100,每个数字不超过10000。
输入数据中没有重复的数字。
输出格式
输出该排序二叉树的横向表示。为了便于评卷程序比对空格的数目,请把空格用句点代替
样例输入1
10 5 20
样例输出1
...|-20
10-|
...|-5
10-|
...|-5
样例输入2
5 10 20 8 4 7
样例输出2
.......|-20
..|-10-|
..|....|-8-|
..|........|-7
5-|
..|-4
..|-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

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


浙公网安备 33010602011771号