【算法】中序遍历二叉树-层级遍历(记录篇)

在这里插入图片描述

算法题目:
给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。

示例:
二叉树:[3,9,20,null,null,15,7],

    3
   / \
  9  20
    /  \
   15   7

返回其层序遍历结果:

[
  [3],
  [9,20],
  [15,7]
]

通过次数294,770提交次数459,173


解题思路

第一感思维:遍历整棵树,那么我不知道哪个节点是哪一层的,我只能从左边遍历到底,然后在遍历右边(前序遍历)。那么怎么才能把树的数据封装到一个二维数组呢?

解决方案一(记录错误思维):

我遍历的时候加入index层级,每次遍历+1,那么是不是我就能每层都存储呢?答案是不行的,就算再加多少个index都无法准确的知道到底这个节点是第几层。

解决方案二

通过递归的方式来解决,每次递归把当前的层级号为入参,所以每次执行递归的时候我们就能知道你是第几层级,然后根据自己的层级号去res集合中get(index)对应的层级的集合List,把当前节点的值add到对应的层级的集合List当中,最后输出list;

话不多说直接上代码


public void runFunc2() {
    TreeNode root = new TreeNode(3);
    TreeNode root1 = new TreeNode(9);
    TreeNode root2 = new TreeNode(20);
    TreeNode root3 = new TreeNode(15);
    TreeNode root4 = new TreeNode(7);
    root.left = root1;
    root.right = root2;
    root.right.left = root3;
    root.right.right = root4;
    List<List<Integer>> res = new ArrayList<>();
    TreeLevelTraversal.levelOrder2(root,res,1);
    System.out.println(res);
}
public static void levelOrder2(TreeNode root, List<List<Integer>> list,int index) {
    if(list.size()<index){
        list.add(new ArrayList<Integer>());
    }
    list.get(index-1).add(root.val);
    if(root.left != null)
        levelOrder2(root.left, list,index+1);
    if(root.right != null)
        levelOrder2(root.right, list,index+1);
}
解决方案三

通过队列的方式来遍历(中序遍历),每次循环先把当前队列里数据的个数得到,遍历取出刚才每一个节点的值,最后把当前节点的子节点加入二维数组,直到最后list为空
代码实现:

public void runFunc() {
        TreeNode root = new TreeNode(3);
        TreeNode root1 = new TreeNode(9);
        TreeNode root2 = new TreeNode(20);
        TreeNode root3 = new TreeNode(15);
        TreeNode root4 = new TreeNode(7);
        root.left = root1;
        root.right = root2;
        root.right.left = root3;
        root.right.right = root4;
        System.out.println(TreeLevelTraversal.levelOrder(root));
    }

    public static List<List<Integer>> levelOrder(TreeNode root) {
        if(root==null){
            return new ArrayList<>();
        }
        List<List<Integer>> result = new ArrayList<>();
        LinkedList<TreeNode> list = new LinkedList<>();
        list.add(root);
        List<Integer> root1 = new ArrayList<>();
        while (!list.isEmpty()) {
            int n = list.size();
            root1 = new ArrayList<>();
            for (int i = 0; i < n; i++) {
                TreeNode treeNode = list.remove();
                root1.add(treeNode.val);
                if (treeNode.left != null) {
                    list.add(treeNode.left);
                }
                if (treeNode.right != null) {
                    list.add(treeNode.right);
                }
            }
            result.add(root1);
            root1 = null;
        }
        return result;
    }
    

借用网络大神的逻辑图片
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

可以看到,此时队列中的结点是 3、4、5,分别来自第 1 层和第 2 层。这个时候,第 1 层的结点还没出完,第 2 层的结点就进来了,而且两层的结点在队列中紧挨在一起,我们无法区分队列中的结点来自哪一层。

因此,我们需要稍微修改一下代码,在每一层遍历开始前,先记录队列中的结点数量 n(也就是这一层的结点数量),然后一口气处理完这一层的 n 个结点。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值