图解算法面试题之层序输出二叉树并输出行号-map实现

面试官:下面我们写些算法题吧

小猫: 好的

面试官:你实现一下,层序输出二叉树

小猫:好的,刷刷刷写出来了。

面试官:嗯.... 可以。你再写一个,层序输出并且输出行号。

小猫内心:层序输出,并且输出行号,我平常学的时候,只学过层序输出....,哎呀,紧张......

这个那个...... 最后挂了......

小猫回去的路上镇定下来了,输出行号..... 好多种实现方式呢,我怎么当时脑子一片空白....哎呀,还是太紧张了.... 以后一定要学会镇定呀,不然自己有思路也想不出来。。

 

 

 

你有没有因为紧张而影响发挥过呢?另外小猫意识到,知识扩展和前移能力非常重要。遇到生题一定不能紧张,要根据现有的知识进行思考,也许就思考出答案了。

回家后小猫把自己想的几种方式整理一下,兴许下次面试能够用到。

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<LineNumber, queue>初始化 LineNumber=0,queue=[0]

  1. 通过LineNumber 获取队列中队首的节点,输出。
  2. 将输出节点对应的左右孩子节点放入map.Key=LineNumber+1的队列中。
  3. 判断LineNumber对应的本行是否为空,如果为空,则说明本行结束,删除该行对应的队列。并且换行LineNumber++
  4. 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<Integer, Queue<BinaryTreeNode>> treeNodeMap = new HashMap<>();
 // 2.root节点队列
 int levelNumber = 0;
 Queue<BinaryTreeNode> binaryTreeNodes = new LinkedBlockingQueue<>();
 binaryTreeNodes.add(binaryTree);
 treeNodeMap.put(levelNumber, binaryTreeNodes);
 // 输出第一行行号
 System.out.print("第" + levelNumber + "行");
 while (!treeNodeMap.isEmpty()) {
 // 3. 读取当前行
 Queue<BinaryTreeNode> curLineQueue = treeNodeMap.get(levelNumber);
 // 4.读取当前行队首元素
 BinaryTreeNode tmpNode = curLineQueue.remove();
 // 输出
 System.out.print(" " + tmpNode.value + " ");
 // 5.下一行数值,读取队列,或者初始化队列
 Queue<BinaryTreeNode> 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);
 }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值