横着打印二叉树的形状,形状真的和二叉树一样,而不是遍历二叉树
提示:这是比较基础的一个递归方法
题目
横着打印二叉树的形状,形状真的和二叉树一样,而不是遍历二叉树
一、审题
示例:下列二叉树
横着打印二叉树的形状:
输出板上是这样的:
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,可以不考虑空间复杂度,但是面试既要考虑时间复杂度最优,也要考虑空间复杂度最优。