广度优先遍历二叉树
写使用广度优先遍历二叉树的时候,很简单,使用一个队列来收集,再从队头打印、加子元素就可以了,但是如何按照每层一行打印呢。
思路
我的第一想法是,找到二叉树开头或结尾的边界条件即可,根据这个思路,发现边界条件太多,而且很难找到这样的条件。没办法,脑子不够活,把重点集中在了二叉树上,后来看别人的代码,通过队列,来确定分层。 先看下广度优先遍历打印的思路:
- 将头节点放入到队列
- 如果队列不为空,遍历,取出队列的节点,并将左右子节点加入队列,这样的作法,保证了是按照层的结构,一层一层的加入的 代码如下
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;
}
总体很简单,权当记录一下,加强记忆