剑指offer-32 从上往下打印二叉树
微信搜索【程序员画工师】关注更多Java编程技术、数据结构与算法、面试题相关内容。
题目
从上往下打印出二叉树的每个节点,同层节点从左至右打印。
思路
根据题意可以联想到树的层序遍历树(广度优先遍历BFS),BFS可以借助队列来实现,下面具体分析:
因为按层打印的顺序决定应该先打印根结点,所以我们从树的根结点开始分析。
为了接下来能够打印值为8的结点的两个子结点,我们应该在遍历该结点时把值为6和10的两个结点保存到一个队列里,现在队列内就有两个结点了。按照从左到右打印的要求,我们先取出为6的结点。打印出值6之后把它的值分别为5和7的两个结点放入队列。此时队列中有三个结点,值分别为10、5和7。接下来我们从队列中取出值为10的结点。注意到值为10的结点比值为5、7的结点先放入队列,此时又比这两个结点先取出,也是没有问题的。由于值为5、7、9、11的结点都没有子结点,因此只要依次打印即可。整个打印过程如下图所示:
上代码
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Queue;
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) {
ArrayList<Integer> printList = new ArrayList<>();
if(root == null){
return printList ;
}
Queue<TreeNode> levelTraverseQueue = new ArrayDeque();
levelTraverseQueue.offer(root);
while (!levelTraverseQueue.isEmpty()){
TreeNode node = levelTraverseQueue.poll();
printList.add(node.val);
if(node.left!=null){
levelTraverseQueue.offer(node.left);
}
if(node.right!=null){
levelTraverseQueue.offer(node.right);
}
}
return printList;
}
}
LinkedList自带API,可以当作队列使用,原理同上。
举一反三
广度优先遍历图或者树,都要用到队列。首先把起始节点放入队列,接下来每次从队列的头部去除一个节点,遍历这个节点之后把他能到达的节点都依次放入队列。重复这个遍历过程,知道队列中的节点全部被遍历为止。
References
[1] 《剑指offer(第二版)》 何海涛著
程序员画工师公众号,获取更多详细Java、Python、C、前端、小程序、产品相关学习资料,欢迎交流