继上一篇图解算法面试题之层序输出二叉树并输出行号-map实现之后,继续进行第二种方式的实现。
我们这次借助辅助变量,不需要多余的map结构来实现行号的输出。
int curLineNumber = 0;// 当前正在打印的行int curLineCount = 1;// 当前行的节点数量int nextLineCount = 0;// 下一行的节点数量
01 解释
思路就是用curLineNumber记录正在输出的是第几行,curLineCount本行有多少个节点数,每打印一个做减一操作,当为0时,curLineNumber++就是换行啦。
nextLineCount在打印一行的时候,用来计算下一行的数量。一行永远是在一起打印的,所以计算下一行不会有错。当换行时,nextLineCount初始化为0;
还是用队列完成输出的过程。
下面图形详解:
第一行输出过程
初始化①当前行为第0行,curLineNumber=0,②队列元素queue中为root元素。
③当前行的节点数量为1 curLineCount=1,④下一行节点数量为0 nextLineCount=0;
弹出队首元素0,输出,curLineCount--;curLineCount=0;
将0的1,2子孩子进入队列,下一行元素数量nextLineCount+=2;
由于curLineCount=0,当前行输入完成。
换行curLineNumber++;curLineCount=nextLineCount;nextLineCount=0;
第二行输出过程
弹出队首元素1,输出。当前行数量减一,curLineCount--;curLineCount=1
将1的左右孩子3,4节点入队,nextLineCount加2。nextLineCount=2;
将队首元素2弹出队列并且输出。curLineCount--;curLineCount=0
将2的左右孩子节点5,6。进入队列,nextLineCount+=2;nextLineCount=4;
由于此时,curLineCount=0,当前行的值已经为空。换行curLineNumber+=1,
置换当前行值,curLineCount=nextLineCount;nextLineCount=0;
重复上述操作到队列为空。
02 总结
1.我们初始化了四个值:①当前行号curLineNumber=0,②当前行对应的数量curLineCount=1。③下一行数量nextLineCount=0;④队列queue=[root]
2.在输出当前行的值以后,curLineCount--。并且判断输出的值的左右孩子节点是否存在,对下一行的节点数量nextLineCount进行计算。
3.当curLineCount=0时换行,即curLineNumber++;同时置换curLineCount=nextLineCount;nextLineCount=0;
4.循环到队列为空时结束。
03 其他实现
实现方式不止一种,还有其他比如,方法(1)在树的节点中加上一个多余的字段用于标记是第几层。但是需要和面试官沟通是否允许多加字段。
方法(2)用一个占位符,比如Integer.MaxValue. 在队列中,放入初始化节点root,同时在放一个占位符表示这一行的结束。通常一行节点输出结束,那么它的下一行节点也刚好进入队列完毕,所以此时可以在队列里放一个占位符表示下一行的结束。
小伙伴们还有其他实现想法吗?
04 代码实现
public static void printBinaryTree1(BinaryTreeNode binaryTree) { if (binaryTree == null) { return; } int curLineNumber = 0; int curLineCount = 1; int nextLineCount = 0; Queue treeNodeQueue = new LinkedBlockingQueue<>(); treeNodeQueue.add(binaryTree); System.out.print("第" + curLineNumber + "行 "); while (!treeNodeQueue.isEmpty()) { BinaryTreeNode tmpTreeNode = treeNodeQueue.remove(); System.out.print(tmpTreeNode.value + " "); curLineCount --; if (tmpTreeNode.leftChild != null) { treeNodeQueue.add(tmpTreeNode.leftChild); nextLineCount ++; } if (tmpTreeNode.rightChild != null) { treeNodeQueue.add(tmpTreeNode.rightChild); nextLineCount ++; } if (curLineCount <= 0) { curLineCount = nextLineCount; nextLineCount = 0; curLineNumber ++; if (!treeNodeQueue.isEmpty()) { System.out.println(); System.out.print("第" + curLineNumber + "行 "); } } }}