面试官:下面我们写些算法题吧
小猫: 好的
面试官:你实现一下,层序输出二叉树
小猫:好的,刷刷刷写出来了。
面试官:嗯.... 可以。你再写一个,层序输出并且输出行号。
小猫内心:层序输出,并且输出行号,我平常学的时候,只学过层序输出....,哎呀,紧张......
这个那个...... 最后挂了......
小猫回去的路上镇定下来了,输出行号..... 好多种实现方式呢,我怎么当时脑子一片空白....哎呀,还是太紧张了.... 以后一定要学会镇定呀,不然自己有思路也想不出来。。
你有没有因为紧张而影响发挥过呢?另外小猫意识到,知识扩展和前移能力非常重要。遇到生题一定不能紧张,要根据现有的知识进行思考,也许就思考出答案了。
回家后小猫把自己想的几种方式整理一下,兴许下次面试能够用到。
01 题目
给你一颗二叉树,层序输出二叉树,并输出行号。
如
输出结果如下:
第一行:0
第二行:1,2
第三行:3, 4,5,6
第四行:7
02 解题
在此说明解法不唯一,如果有其他更好想法,欢迎一起交流。
我们在层序输出二叉树的时候,会用队列完成,如果有不会的可以看上篇文章的解释
层序输出二叉树动态图解,那么如何输出行号呢,如何确定这一行已经结束了呢。
既然要一行一行暑促,我可以把每行元素放在一个队列里面,用行号标记这个队列。那么
即Map<行号,队列装一行元素> map结构刚好能够实现这个思路。nice!
接下来,我们用图详细解释
0.初始化LineNumber=0,Map 对应key=LineNumber,value=queue[0]
1.map获取LineNumber=0的队列queue=[0] ,弹出队首元素,并输出。
把0的左右孩子节点1,2,放入key=lineNumber+1 第1行的队列中
由于LineNumber=0第0行的队列为空,说明这一行已经全部输出,删除map中空队列,并且行号加一LineNumber++ LineNumber=1
2.获取LineNumber=1,的队首元素1,输出
将1的左右孩子节点,3,4放入下一行的队列中
继续弹出第1行元素2,并且输出
将2对应的左右孩子节点放入LineNumber+1对应的队列中
此时LineNumber=1对应的队列为空,说明此行已经输出完毕,删除map中的该队列,换行LIneNumber++
接下来重复上述步骤,直到map为空结束。
03 总结
Map
04 代码实现
import java.util.Queue;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.LinkedBlockingQueue;
public class 面试题23层序打印二叉树进阶 {
/**
* 层序打印二叉树并输出行号
*/
public static void printBinaryTree(BinaryTreeNode binaryTree) {
if (binaryTree == null) {
return;
}
// 1.一个总的map
Map> treeNodeMap = new HashMap<>();
// 2.root节点队列
int levelNumber = 0;
Queue binaryTreeNodes = new LinkedBlockingQueue<>();
binaryTreeNodes.add(binaryTree);
treeNodeMap.put(levelNumber, binaryTreeNodes);
// 输出第一行行号
System.out.print("第" + levelNumber + "行");
while (!treeNodeMap.isEmpty()) {
// 3. 读取当前行
Queue curLineQueue = treeNodeMap.get(levelNumber);
// 4.读取当前行队首元素
BinaryTreeNode tmpNode = curLineQueue.remove();
// 输出
System.out.print(" " + tmpNode.value + " ");
// 5.下一行数值,读取队列,或者初始化队列
Queue nextLineQueue = treeNodeMap.getOrDefault(levelNumber + 1, new LinkedBlockingQueue<>());
if (tmpNode.leftChild != null) { // 不为空,王下一行队列里加
nextLineQueue.add(tmpNode.leftChild);
}
if (tmpNode.rightChild != null) {// 不为空,王下一行队列里加
nextLineQueue.add(tmpNode.rightChild);
}
if (nextLineQueue.size() > 0) {// 如果不为空,重新put以下,防止对于初始化的队列,没有在map里面
treeNodeMap.put(levelNumber + 1, nextLineQueue);
}
//5.当前行输出完毕的话,删除当前行map key,value,行号++
if (curLineQueue.size() <= 0) {// 当前行已经输出完毕
treeNodeMap.remove(levelNumber);
levelNumber ++;
}
// 6. 当前行已经结束,但是不是最后一行输出行号
if (curLineQueue.size() <= 0 && !treeNodeMap.isEmpty()) {
System.out.println();
System.out.print("第" + levelNumber + "行");
}
}
}
public static void main(String[] args) {
BinaryTreeNode treeNode7 = new BinaryTreeNode(null, null, 7);
BinaryTreeNode treeNode6 = new BinaryTreeNode(null, null, 6);
BinaryTreeNode treeNode5 = new BinaryTreeNode(treeNode7, null, 5);
BinaryTreeNode treeNode4 = new BinaryTreeNode(null, null, 4);
BinaryTreeNode treeNode3 = new BinaryTreeNode(null, null, 3);
BinaryTreeNode treeNode2 = new BinaryTreeNode(treeNode5, treeNode6, 2);
BinaryTreeNode treeNode1 = new BinaryTreeNode(treeNode3, treeNode4, 1);
BinaryTreeNode treeNode = new BinaryTreeNode(treeNode1, treeNode2, 0);
printBinaryTree(treeNode);
}
}