1二叉树的层序遍历
层序遍历一个二叉树。就是从左到右一层一层的去遍历二叉树。这种遍历的方式和我们之前讲过的都不太一样。
需要借用一个辅助数据结构即队列来实现,队列先进先出,符合一层一层遍历的逻辑,而是用栈先进后出适合模拟深度优先遍历也就是递归的逻辑。
而这种层序遍历方式就是图论中的广度优先遍历,只不过我们应用在二叉树上。
使用队列实现二叉树广度优先遍历,动画如下:
代码实现如下:
//二叉树的层次遍历
public static class Solution3{
public List<List<Integer>> resList = new ArrayList<List<Integer>>();
public List<List<Integer>> levelOrder(TreeNode root) {
// checkFun01(root,0);
checkFun02(root);
return resList;
}
BFS--迭代方式--借助队列
private void checkFun02(TreeNode root) {
if (root==null)return;
Queue<TreeNode> queue=new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()){
List<Integer> list = new ArrayList<>();//存放每一层的数据
int size = queue.size();
while (size>0){
TreeNode node = queue.poll();
list.add(node.val);
if (node.left!=null) queue.offer(node.left);
if (node.right!=null) queue.offer(node.right);
size--;
}
resList.add(list);
}
}
//DFS--递归方式
private void checkFun01(TreeNode root, int deep) {
if (root==null)return;
deep++;
if (resList.size()<deep){
List<Integer> list = new ArrayList<>();//存放每一层的数据
resList.add(list);
}
resList.get(deep-1).add(root.val);
checkFun01(root.left,deep);
checkFun01(root.right,deep);
}
}
2二叉树的层次遍历 II
给定一个二叉树,返回其节点值自底向上的层次遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)
思路:
相对于102.二叉树的层序遍历,就是最后把result数组反转一下就可以了。
实现代码如下:
// 二叉树的层序遍历 II
public static class Solution4{
/**
* 解法:队列,迭代。
* 层序遍历,再翻转数组即可。
*/
public List<List<Integer>> solution1(TreeNode root) {
Deque<TreeNode> que = new LinkedList<>();
List<List<Integer>> list = new ArrayList<>();
if (root == null) {
return list;
}
que.offerLast(root);
while (!que.isEmpty()) {
List<Integer> levelList = new ArrayList<>();
int levelSize = que.size();
for (int i = 0; i < levelSize; i++) {
TreeNode peek = que.peekFirst();
levelList.add(que.pollFirst().val);
if (peek.left != null) {
que.offerLast(peek.left);
}
if (peek.right != null) {
que.offerLast(peek.right);
}
}
list.add(levelList);
}
List<List<Integer>> result = new ArrayList<>();
for (int i = list.size() - 1; i >= 0; i-- ) {
result.add(list.get(i));
}
return result;
}
}
二叉树的右视图
给定一棵二叉树,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。
思路:
层序遍历的时候,判断是否遍历到单层的最后面的元素,如果是,就放进result数组中,随后返回result就可以了。
代码实现如下:
//二叉树的右视图
public static class Solution5{
/**
* 解法:队列,迭代。
* 每次返回每层的最后一个字段即可。
*
* 小优化:每层右孩子先入队。代码略。
*/
public List<Integer> rightSideView(TreeNode root) {
List<Integer> list = new ArrayList<>();
Deque<TreeNode> que = new LinkedList<>();
if (root == null) {
return list;
}
que.offerLast(root);
while (!que.isEmpty()) {
int levelSize = que.size();
for (int i = 0; i < levelSize; i++) {
TreeNode poll = que.pollFirst();
if (poll.left != null) {
que.addLast(poll.left);
}
if (poll.right != null) {
que.addLast(poll.right);
}
if (i == levelSize - 1) {
list.add(poll.val);
}
}
}
return list;
}
}
二叉树的层平均值
给定一个非空二叉树, 返回一个由每层节点平均值组成的数组。
思路:
本题就是层序遍历的时候把一层求个总和在取一个均值
//二叉树的层平均值
public static class Solution6{
/**
* 解法:队列,迭代。
* 每次返回每层的最后一个字段即可。
*/
public List<Double> averageOfLevels(TreeNode root) {
List<Double> list = new ArrayList<>();
Deque<TreeNode> que = new LinkedList<>();
if (root == null) {
return list;
}
que.offerLast(root);
while (!que.isEmpty()) {
TreeNode peek = que.peekFirst();
int levelSize = que.size();
double levelSum = 0.0;
for (int i = 0; i < levelSize; i++) {
TreeNode poll = que.pollFirst();
levelSum += poll.val;
if (poll.left != null) {
que.addLast(poll.left);
}
if (poll.right != null) {
que.addLast(poll.right);
}
}
list.add(levelSum / levelSize);
}
return list;
}
}