分为两种:
1.第一种是直接将遍历的数据保存到列表里;
2.第二种是将每一层的数据以列表形式保存在列表;(今天要讲述的内容)
代码如下,思想在后
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> res = new ArrayList<>();
Queue<TreeNode> q=new LinkedList<>();
q.offer(root);
while(!q.isEmpty()){
int size=q.size();
List<Integer> level=new LinkedList<>();
for(int i=0;i<size;++i){
TreeNode cur= q.peek();
q.poll();
if(cur==null){
continue;
}
level.add(cur.val);
q.offer(cur.left);
q.offer(cur.right);
}
if(!level.isEmpty()){
res.add(level);
}
}
return res;
}
}
对于第二种情况。我们都知道二叉树的层序遍历符合队列的先进先出,栈的后进先出符合深度优先遍历即就是递归。
在层序遍历中:
(1)首先定义一个放结果的列表,再定义一个队列,将我们传入的根节点首先存放到队列中;
(2)如果传入的队列不为空,那么计算当前队列中的数据长度,再定义一个存放当前层的节点值的列表level;
(3)循环遍历队列中的节点,因为我们要每一层的节点数都能够正确读出,就需要确定当前列表有多个节点,也就是当前层在队列中有几个元素。也就是q.size();
(4)在删除当前队列的结点之前,我们需要定义一个指针读取到当前节点元素,以便后面寻找她的左右孩子加入队列,因此定义一个cur指针指向q.peek();再将q删除,以便下一层节点的进入。
(5)将取到的值加入到level中,再将cur指向的左右孩子加入到队列中(此时已经为空),如果当前level不为空,也就是将一层的节点从队列中都遍历完成,则将level添加到结果集res中,继续重复上述操作。
补充知识点:
List<List> res = new ArrayList<>(); 定义了一个二维List,即一个List中存放了多个List,用于存储树的层次遍历结果。
Queue q=new LinkedList<>(); 定义了一个FIFO队列,用于存储待遍历的树节点。
List level=new LinkedList<>(); 定义了一个List,用于存储每一层的节点值。
ArrayList底层是基于数组实现的,它支持快速随机访问元素,因此对于大量的访问操作,ArrayList的性能优于LinkedList。但是,在插入和删除元素时,由于需要移动数组中的元素位置,所以ArrayList的性能比LinkedList差。
LinkedList底层是基于双向链表实现的,它支持高效的元素插入和删除操作,因为只需要改变相邻元素之间的指针。但是,随机访问的性能较差,因为需要遍历链表才能访问指定位置的元素。