广度优先遍历(BFS)二叉树,分层打印

445 阅读1分钟

广度优先遍历二叉树

写使用广度优先遍历二叉树的时候,很简单,使用一个队列来收集,再从队头打印、加子元素就可以了,但是如何按照每层一行打印呢。

思路

我的第一想法是,找到二叉树开头或结尾的边界条件即可,根据这个思路,发现边界条件太多,而且很难找到这样的条件。没办法,脑子不够活,把重点集中在了二叉树上,后来看别人的代码,通过队列,来确定分层。 先看下广度优先遍历打印的思路:

  • 将头节点放入到队列
  • 如果队列不为空,遍历,取出队列的节点,并将左右子节点加入队列,这样的作法,保证了是按照层的结构,一层一层的加入的 代码如下
public static int[] levelOrder(TreeNode root) {
    if(root==null)
        return new int[0];

    Queue<TreeNode> help = new LinkedList<>();
    help.add(root);
    List<Integer> result=new ArrayList<>();
    while (!help.isEmpty()) {
        TreeNode node = help.poll();
        result.add(node.val);
        if (node.left != null)
            help.add(node.left);
        if (node.right != null)
            help.add(node.right);
    }

    int[] re=new int[result.size()];
    for (int i = 0; i < result.size(); i++) {
        re[i]=result.get(i);
    }

    return re;
}

再回到分层打印的思路里,只要基于这个代码,给出层的划分就可以了。

如何划分层

从队列入手,二叉树的结构是层层递进的,加入队列后,第一层是head,进入循环,取出head,加入head的左右节点,这时,队列里只有左右两个节点,刚好是第二层的所有节点。继续取出,这个时候会加入head左右节点的左右节点,此时,head左右节点被取出,队列中剩余的刚好是第三层的节点。 也就是说,我们可以通过队列的长度来控制层的打印,代码如下:

public List<List<Integer>> levelOrder(TreeNode root) {
     List<List<Integer>> result=new ArrayList<>();
         if(root==null)
             return result;

         Queue<TreeNode> help=new LinkedList<>();
         help.add(root);

         while (help.size()>0){
             // 记录当前队列中的节点个数
             int size=help.size();
             List<Integer> currentResult=new ArrayList<>();
             // 取这一层的节点
             for (int i = 0; i < size; i++) {
                 TreeNode current=help.poll();
                 currentResult.add(current.val);
                 if(current.left!=null){
                     help.add(current.left);
                 }
                 if(current.right!=null){
                     help.add(current.right);
                 }
             }
             result.add(currentResult);
         }

         return result;
 }

总体很简单,权当记录一下,加强记忆