(二叉树)原来二叉树的层序遍历这么简单!!!

文章目录

    • 一、层序遍历
    • 二、层序遍历II
    • 三、二叉树的右视图
    • 四、 二叉树的层平均值
    • 五、N 叉树的层序遍历
    • 六、总结

一、层序遍历

层序遍历一个二叉树。就是从左到右一层一层的去遍历二叉树

需要借用一个辅助数据结构即队列来实现,队列先进先出,符合一层一层遍历的逻辑

这种层序遍历方式就是图论中的广度优先遍历,只不过我们应用在二叉树上
(二叉树)原来二叉树的层序遍历这么简单!!!_第1张图片

class Solution {
     
    public List<List<Integer>> levelOrder(TreeNode root) {
     
        List<List<Integer>> lists = new ArrayList<>();
        List<Integer> list;
        //队列,遍历节点使用
        Deque<TreeNode> deque = new LinkedList<>();
        deque.add(root);
        TreeNode node;
        //记录每一层的节点
        int size;
        while (!deque.isEmpty()) {
     
            size = deque.size();
            list = new ArrayList<>();
            //保证每次出一层节点
            while (size > 0) {
     
                node = deque.poll();
                list.add(node.val);
                if (node.left != null) {
     
                    deque.add(node.left);
                }
                if (node.right != null) {
     
                    deque.add(node.right);
                }
                size--;
            }
            lists.add(list);
        }
        return lists;
    }
}

二、层序遍历II

(二叉树)原来二叉树的层序遍历这么简单!!!_第2张图片
与正常的层序遍历相比,只需要翻转下 lists 即可

Collections.reverse(lists);
import java.util.*;

class Solution {
     
    public List<List<Integer>> levelOrderBottom(TreeNode root) {
     
        List<List<Integer>> lists = new ArrayList<>();
        if (root == null) {
     
            return lists;
        }
        List<Integer> list;
        //队列,遍历节点使用
        Deque<TreeNode> deque = new LinkedList<>();
        deque.add(root);
        TreeNode node;
        //记录每一层的节点
        int size;
        while (!deque.isEmpty()) {
     
            size = deque.size();
            list = new ArrayList<>();
            //保证每次出一层节点
            while (size > 0) {
     
                node = deque.poll();
                list.add(node.val);
                if (node.left != null) {
     
                    deque.add(node.left);
                }
                if (node.right != null) {
     
                    deque.add(node.right);
                }
                size--;
            }
            lists.add(list);
        }
        //翻转集合
        Collections.reverse(lists);
        return lists;
    }
}

三、二叉树的右视图

给定一棵二叉树,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值
(二叉树)原来二叉树的层序遍历这么简单!!!_第3张图片
题目要求,记录最右侧的节点,所以只需要层序遍历,输出单层遍历的最后一个节点即可

class Solution {
     
    public List<Integer> rightSideView(TreeNode root) {
     
        if (root == null) {
     
            return new ArrayList();
        }
        List<Integer> list = new ArrayList<>();
        Deque<TreeNode> deque = new LinkedList<>();
        TreeNode node;
        deque.add(root);
        while (!deque.isEmpty()) {
     
            int size = deque.size();
            while (size > 0) {
     
                node = deque.poll();
                //记录每层最后一个节点
                if (size == 1) {
     
                    list.add(node.val);
                }
                if (node.left != null) {
     
                    deque.add(node.left);
                }
                if (node.right != null) {
     
                    deque.add(node.right);
                }
                size--;
            }
        }
        return list;
    }
}

四、 二叉树的层平均值

(二叉树)原来二叉树的层序遍历这么简单!!!_第4张图片
同样层序遍历,然后记录每一行的平均值即可

class Solution {
     
    public List<Double> averageOfLevels(TreeNode root) {
     
        if (root == null) {
     
            return new ArrayList();
        }
        List<Double> list = new ArrayList<>();
        Deque<TreeNode> deque = new LinkedList<>();
        TreeNode node;
        int size;
        double sum;
        int len;
        deque.add(root);
        while (!deque.isEmpty()) {
     
            size = deque.size();
            len = size;
            sum = 0;
            while (size > 0) {
     
                node = deque.poll();
                //sum 记录每层的总和
                sum += node.val;
                if (node.left != null) {
     
                    deque.add(node.left);
                }
                if (node.right != null) {
     
                    deque.add(node.right);
                }
                size--;
            }
            list.add(sum / len);
        }
        return list;
    }
}

五、N 叉树的层序遍历

给定一个 N 叉树,返回其节点值的层序遍历。(即从左到右,逐层遍历)。

树的序列化输入是用层序遍历,每组子节点都由 null 值分隔(参见示例)。

(二叉树)原来二叉树的层序遍历这么简单!!!_第5张图片
题目和二叉树的方法类似,只是将原先的判断左右子树,改为判断是否有孩子节点

class Solution {
     
    public List<List<Integer>> levelOrder(Node root) {
     
        if (root == null) {
     
            return new ArrayList();
        }
        List<List<Integer>> lists = new ArrayList<>();
        List<Integer> list;
        Deque<Node> deque = new LinkedList<>();
        deque.add(root);
        Node node;
        int size;
        while (!deque.isEmpty()) {
     
            list = new ArrayList<>();
            size = deque.size();
            while (size > 0) {
     
                node = deque.poll();
                list.add(node.val);
                //由原来的判断走右子树,改为判断是否有孩子节点
                for (Node temp : node.children) {
     
                    deque.add(temp);
                }
                size--;
            }
            lists.add(list);
        }
        return lists;
    }
}

六、总结

所谓的层序遍历就是图论中的广度优先搜索,需要借助队列实现

Deque<Node> deque = new LinkedList<>();

每层的节点需要借助size来记录

		while (!deque.isEmpty()) {
     
            size = deque.size();
            list = new ArrayList<>();
            //保证每次出一层节点
            while (size > 0) {
     
                node = deque.poll();
                list.add(node.val);
                if (node.left != null) {
     
                    deque.add(node.left);
                }
                if (node.right != null) {
     
                    deque.add(node.right);
                }
                size--;
            }
            lists.add(list);
        }

你可能感兴趣的:(二叉树,队列,数据结构)