非递归算法:
用队列,关键是对入队的结点进行划分,计算当前层次的结点总数;
一,下一层的结点总数的计算:
法一:
从上一层第一个结点开始出队到上一层最后一个结点出对完成时,下一层所有结点刚好完成了入队操作;在此段时间内不断更新计数器可计算出下一层的节点总数;此时用下一层结点总数更新当前结点总数值;
法二:
外层每一次循环(while(){})都是一层,所以直接在外层调用 queue.size()即为当前层次结点的总数;
二,List<List>类型(以线性表为元素的线性表)的集合的操作;
声明:List<List> list = new ArrayList<List<Integer>>();
添加外层表的元素:list.add(new ArrayList());
添加表的表的元素(整型值)list.get(level).add(tmp.val);
三,队列的使用
声明:Queue queue = new LinkedList();
入队:queue.add(root);
出队:tmp = queue.remove();
判断队空:queue.isEmpty()
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> list = new ArrayList<List<Integer>>();
if(root == null) return list;//对空树,返回[]
Queue<TreeNode> queue = new LinkedList<TreeNode>();
TreeNode tmp=null;//用于存储当前出队元素
int level = 0, currentLevelSize=1;//level:当前层次,currentLevelSize:当前层次元素个数
queue.add(root);
while(!queue.isEmpty())
{
int nextLevelSize =0;//下一层元素的个数
list.add(new ArrayList<Integer>());
for(int i=0;i<currentLevelSize;i++)
{
tmp = queue.remove();
list.get(level).add(tmp.val);
if(tmp.left!=null)
{
queue.add(tmp.left);
nextLevelSize++;
}
if(tmp.right!=null)
{
queue.add(tmp.right);
nextLevelSize++;
}
}
currentLevelSize = nextLevelSize;
level++;
}
return list;
}
}
递归算法:(面试题考过)
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
List<List<Integer>> list = new ArrayList<List<Integer>>();
public void preOrder(TreeNode root, int level)//这里用的前序遍历,中序,后序也可
{
if(list.size()==level) list.add(new ArrayList<Integer>());//关键,list,只创建四个新表
list.get(level).add(root.val);
if(root.left!=null) preOrder(root.left,level+1);
if(root.right!=null) preOrder(root.right,level+1);
}
public List<List<Integer>> levelOrder(TreeNode root) {
if(root == null) return list;
preOrder(root,0);
return list;
}
}
层序递归遍历关键在于何时创建list的子表(当list.size()==level时)。
只要能完全遍历整颗二叉树,就可以将各个结点的值填入对应的位置;(list.get(level).add(root.val);)