题目描述
从上往下打印出二叉树的每个节点,同层节点从左至右打印。
思路分析
这道题实际上考察的就是二叉树的层次遍历。以下图(来自《剑指offer》)为例进行分析:
因为按层打印的顺序决定应该先打印根结点,所以我们从树的根结点开始分析。为了接下来能够打印值为9的结点的两个子结点,我们应该在遍历到该结点的时候把值为6和10的两个结点保存到一个容器里,现在容器内就有两个结点了。按照从左到右打印的要求,我们先取出值为6的结点。打印出6之后把它的值分别为5和7的两个子结点放入数据容器,此时容器中有3个结点,值分别是10、5、7。接下来从容器中取出10的结点,注意到值为10的结点比值为5、7的结点先放入容器,此时又比这两个结点先取出,这就是“先进先出”典型的队列。由于值为5、7、9、11的结点都没有子结点,因此只要依次打印即可。
通过上面例子分析,我们可找到从上到下打印二叉树的规律:每一次打印一个结点的时候,如果该结点有子结点,则把该结点的子结点放到队列的末尾。接下来到队列的头部取出最早进入队列的结点,重复前面的操作,直至队列为空。
Java实现
import java.util.ArrayList;
import java.util.LinkedList;
/**
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> list=new ArrayList<Integer>();
//判断特殊值
if(root==null)
return list;
//队列保存二叉树层次遍历的结点
LinkedList<TreeNode> queue=new LinkedList<TreeNode>();
queue.addLast(root);
while(queue.size()>0){
TreeNode p=queue.removeFirst();
list.add(p.val);
if(p.left!=null)
queue.addLast(p.left);
if(p.right!=null)
queue.addLast(p.right);
}
return list;
}
}
启发:
不管是广度优先遍历一个有向图还是一棵树,都要用到队列。第一步我们把起始结点(对树而言是根结点)放入队列中。接下来每一次从队列的头部取出一个结点,遍历这个结点之后把它能到达的结点(对树而言是子结点)都一次放入队列中,重复这个遍历过程,直到队列为空为止。