二叉树的打印
按层遍历
计算位置
public static String print(BiNode node) {
if (node == null) {
return "";
}
List<List<Integer>> arr = new ArrayList<>();
Queue<BiNode> currLevel = new LinkedList<>();
currLevel.add(node);
Queue<BiNode> nextLevel = new LinkedList<>();
Queue<BiNode> tempLevel;
BiNode temp;
boolean allNull;
// 数字的最大长度
int maxValueLength = 0;
// 按层遍历,不能忽略空节点
while (true) {
allNull = true;
List<Integer> list = new ArrayList<>();
while (!currLevel.isEmpty()) {
temp = currLevel.poll();
list.add(temp == null ? null : temp.value);
if (temp != null) {
maxValueLength = Math.max(maxValueLength, length(temp.value) + (temp.value < 0 ? 1 : 0));
}
nextLevel.add(temp == null || temp.left == null ? null : temp.left);
nextLevel.add(temp == null || temp.right == null ? null : temp.right);
if (allNull && temp != null && (temp.left != null || temp.right != null)) {
allNull = false;
}
}
arr.add(list);
if (allNull) {
break;
}
tempLevel = nextLevel;
nextLevel = currLevel;
currLevel = tempLevel;
}
// 空节点占位符
String placeholder = (maxValueLength == 1 ? "" : space(maxValueLength - 1)) + "#";
List<String> arr2 = new ArrayList<>();
// 按层输出
int N = arr.size();
for (int i = 0; i < N; i++) {
List<Integer> list = arr.get(i);
StringBuilder sb = new StringBuilder();
// 第一个元素与边界的距离
sb.append(space((((int) Math.pow(2, N - 1 - i)) - 1) * maxValueLength));
// 两元素之间的空隙
String gapSpace = space((((int) Math.pow(2, N - i)) - 1) * maxValueLength);
for (int j = 0; j < list.size(); j++) {
Integer v = list.get(j);
sb.append(v == null ? placeholder : formatNumber(v, maxValueLength));
sb.append(gapSpace);
}
arr2.add(sb.toString());
}
return String.join("\n", arr2);
}
public static int length(int v) {
int i = 1;
while (v / ((int) Math.pow(10, i)) != 0) {
i++;
}
return i;
}
public static String space(int length) {
return String.format("% " + (length + 1) + "d", 0).substring(0, length);
}
public static String formatNumber(int value, int length) {
return String.format("%-" + length + "d", value);
}