https://oj.leetcode.com/problems/binary-tree-level-order-traversal/
这篇写得很好。http://leetcode.com/2010/09/printing-binary-tree-in-level-order.html
Pre-order, in-order, and post-order tree traversal areDepth First Search (DFS), since they visit the tree by proceeding deeper and deeper until it reaches the leaf nodes. Level-order traversal can be implemented Breadth First Search (BFS), since it visits the nodes level by level. (But it can also be implemented by DFS)
http://leetcode.com/2010/09/binary-tree-level-order-traversal-using_17.html
代码还需练更熟。
Time: O(n) = 节点总数,Space: O(n) = 每一层的节点数
方法I: 用两个queue (arraylist)
public class Solution {
public ArrayList<ArrayList<Integer>> levelOrder(TreeNode root) {
ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
if(root == null) return result;
ArrayList<TreeNode> parentsList = new ArrayList<TreeNode>();
ArrayList<TreeNode> childrenList = new ArrayList<TreeNode>();
parentsList.add(root);
while(!parentsList.isEmpty()){
ArrayList<Integer> temp = new ArrayList<Integer>();
for(TreeNode parent : parentsList){
temp.add(parent.val);
if(parent.left != null){
childrenList.add(parent.left);
}
if(parent.right != null){
childrenList.add(parent.right);
}
}
result.add(temp);
parentsList = childrenList;
childrenList = new ArrayList<TreeNode>();
}
return result;
}
}
方法II: 用1个queue, 两个数(一个记录当前层节点数,一个记录下一层节点数)
public class Solution {
public ArrayList<ArrayList<Integer>> levelOrder(TreeNode root) {
ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
if(root == null) return result;
ArrayList<TreeNode> nodeList = new ArrayList<TreeNode>();
nodeList.add(root);
int curLevelNode = 1;
int nextLevelNode = 0;
ArrayList<Integer> tmp = new ArrayList<Integer>();
while(!nodeList.isEmpty()){
TreeNode node = nodeList.remove(0);
curLevelNode --;
tmp.add(node.val);
if(node.left!= null){
nodeList.add(node.left);
nextLevelNode ++;
}
if(node.right!= null){
nodeList.add(node.right);
nextLevelNode ++;
}
if(curLevelNode == 0){
result.add(tmp);
tmp = new ArrayList<Integer>();
curLevelNode = nextLevelNode;
nextLevelNode = 0;
}
}
return result;
}
}
更新:@8.25.2014
1 我把while循环写成这样:
是错误的。因为只有当curLevelNodeNum=0时,才加入它的children 。那除了当前层的最后一个节点,其他节点的children 都会被漏掉。如下:2的 children {4, 5}就被漏掉了。
Input: | {1,2,3,4,5} |
Output: | [[1],[2,3]] |
Expected: | [[1],[2,3],[4,5]] |
while(!queue.isEmpty()){
TreeNode n = queue.poll();
list.add(n.val);
curLevelNodeNum --;
if(curLevelNodeNum == 0){
result.add(list);
list = new ArrayList<Integer>();
if(n.left != null) {
queue.add(n.left);
nextLevelNodeNum++;
}
if(n.right != null) {
queue.add(n.right);
nextLevelNodeNum++;
}
curLevelNodeNum = nextLevelNodeNum;
nextLevelNodeNum = 0;
}
}
2 这个代码还可以优化。
public class Solution {
public ArrayList<ArrayList<Integer>> levelOrder(TreeNode root) {
ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
if(root == null) return result;
LinkedList<TreeNode> queue = new LinkedList<TreeNode>();
queue.add(root);
int curLevelNodeNum = 1;
int nextLevelNodeNum = 0;
ArrayList<Integer> list = new ArrayList<Integer>();
while(!queue.isEmpty()){
TreeNode n = queue.poll();
list.add(n.val);
curLevelNodeNum --;
if(n.left != null) {
queue.add(n.left);
//nextLevelNodeNum++;
}
if(n.right != null) {
queue.add(n.right);
//nextLevelNodeNum++;
}
if(curLevelNodeNum == 0){
result.add(list);
list = new ArrayList<Integer>();
curLevelNodeNum = queue.size();
//curLevelNodeNum = nextLevelNodeNum;
//nextLevelNodeNum = 0;
}
}
return result;
}
}
3 Approach III
public class Solution {
//use delimiter node
public ArrayList<ArrayList<Integer>> levelOrder(TreeNode root) {
ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
LinkedList<TreeNode> queue = new LinkedList<TreeNode>();
TreeNode delimiter = new TreeNode(0);//what if there also exist a leaf node val=0?
if(root!=null) {
queue.add(root);
queue.add(delimiter);
}
ArrayList<Integer> list = new ArrayList<Integer>();
while(!queue.isEmpty()){
TreeNode n = queue.poll();
if(n == delimiter){
result.add(list);
list = new ArrayList<Integer>();
if(!queue.isEmpty()){
queue.add(delimiter);
}
}
else{
list.add(n.val);//only add n.val if n!=delimiter
if(n.left != null) {
queue.add(n.left);
}
if(n.right != null) {
queue.add(n.right);
}
}
}
return result;
}
}
Note: 2014. 11. 5
1 Approach I, II: 如果要用两个记录节点数的变量:cur 和next,那么一定要把next = 0;否则,就只用cur一个变量即可。
2 Approach III:
在加上一层的节点以后,不要忘了加上delimiter。
if(!queue.isEmpty()){
queue.add(delimiter);
}