@ 蓝桥杯 练习系统 历届试题 PREV-11
资源限制
时间限制:1.0s 内存限制:256.0MB
问题描述
二叉树可以用于排序。其原理很简单:对于一个排序二叉树添加新节点时,先与根节点比较,若小则交给左子树继续处理,否则交给右子树。
当遇到空子树时,则把该节点放入那个位置。
比如,10 8 5 7 12 4 的输入顺序,应该建成二叉树如下图所示,其中.表示空白。
…|-12
10-|
…|-8-|
…|…|-7
…|-5-|
…|-4
本题目要求:根据已知的数字,建立排序二叉树,并在标准输出中横向打印该二叉树。
输入格式
输入数据为一行空格分开的N个整数。 N<100,每个数字不超过10000。
输入数据中没有重复的数字。
输出格式
输出该排序二叉树的横向表示。为了便于评卷程序比对空格的数目,请把空格用句点代替:
测试样例1
in:
10 5 20
out:
...|-20
10-|
...|-5
测试样例2
in:
5 10 20 8 4 7
out:
.......|-20
..|-10-|
..|....|-8-|
..|........|-7
5-|
..|-4
AC code:
import java.io.IOException;
import java.io.PrintWriter;
import java.io.BufferedReader;
import java.io.StreamTokenizer;
import java.io.InputStreamReader;
public class Main {
static Node root;
static PrintWriter out;
static String regex = "[^.|]";
public static void main(String[] args) throws IOException {
StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
out = new PrintWriter(System.out);
in.nextToken();
root = new Node((int)in.nval, false);
while (in.nextToken() != -1)
insert((int)in.nval, root);
String rootStr = root.value + "-|";
show(root.right, rootStr, true);
out.println(rootStr);
show(root.left, rootStr, false);
out.close();
}
static void show(Node n, String f, boolean ftag) {
if (n == null) return;
String now = f.replaceAll(regex, ".") + "-" + n.value + noLeaf(n);
if (n.tag == ftag) now = pruning(now);
show(n.right, now, n.tag);
out.println(now);
show(n.left, now, n.tag);
}
static void insert(int value, Node n) {
if (value < n.value) {
if (n.left == null) n.left = new Node(value, true);
else insert(value, n.left);
} else {
if (n.right == null) n.right = new Node(value, false);
else insert(value, n.right);
}
}
static String noLeaf(Node n) { return n.left == n.right? "":"-|"; }
static String pruning(String s) {
StringBuilder str = new StringBuilder(s);
int index = str.lastIndexOf("|.");
if (index < 0) return s;
return str.replace(index, index + 2, "..").toString();
}
static class Node {
int value;
boolean tag;
Node left, right;
Node(int value, boolean tag) {
this.value = value;
this.tag = tag;
}
}
}
没有像多数程序一样,记录树枝范围再生产树枝
而是在创建节点时记录该节点是左子树还是右子树
如果同向则裁剪掉上一条树枝,否则继承所有树枝
AGO
没仔细看测试用例
一开始我以为拿到节点的深度再做中梗遍历即可
所以写了个优化版的流程,觉得代码质量害行,想先左树改下 compareTo 两参数的位置就行
import java.io.IOException;
import java.io.BufferedReader;
import java.io.StreamTokenizer;
import java.io.InputStreamReader;
import java.util.Arrays;
public class Main {
public static void main(String[] args) throws IOException {
StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
int v, n, len = -1, dmax[] = new int[100];
Node[] tree = new Node[100];
tree[0] = new Node(0);
tree[0].deep = 1;
while (in.nextToken() != -1) {
tree[++len] = new Node(v = (int)in.nval);
n = 0;
while (true) {
if (v < tree[n].value) {
if (tree[n].left == 0) {
tree[n].left = len;
break;
} else n = tree[n].left;
} else {
if (tree[n].right == 0) {
tree[n].right = len;
break;
} else n = tree[n].right;
}
}
if (v > dmax[tree[len].deep = tree[n].deep + 1]) dmax[tree[len].deep] = v;
}
Arrays.sort(tree, 0, len + 1);
}
static class Node implements Comparable<Node> {
int value, deep, left, right;
Node(int value) {
this.value = value;
}
public int compareTo(Node n) {
return n.value - this.value;
}
}
}