算法打卡第十六天BM26 求二叉树的层序遍历

本文详细介绍了如何通过队列和递归方法实现二叉树的层次遍历,包括过程演示、代码实现及复杂度分析,适合秋招算法学习者参考。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        今天是秋招预备队算法篇打卡第十六天,今天状态不错!

     问题:求二叉树的层序遍历

     描述:

       解题方法:

        1、队列

        二叉树的层次遍历就是按照从上到下每行,然后每行中从左到右依次遍历,得到的二叉树的元素值。对于层次遍历,我们通常会使用队列来辅助:因为队列是一种先进先出的数据结构,我们依照它的性质,如果从左到右访问完一行节点,并在访问的时候依次把它们的子节点加入队列,那么它们的子节点也是从左到右的次序,且排在本行节点的后面,因此队列中出现的顺序正好也是从左到右,正好符合层次遍历的特点。

        具体做法:

  • step 1:首先判断二叉树是否为空,空树没有遍历结果。
  • step 2:建立辅助队列,根节点首先进入队列。不管层次怎么访问,根节点一定是第一个,那它肯定排在队伍的最前面。
  • step 3:每次进入一层,统计队列中元素的个数。因为每当访问完一层,下一层作为这一层的子节点,一定都加入队列,而再下一层还没有加入,因此此时队列中的元素个数就是这一层的元素个数。
  • step 4:每次遍历这一层这么多的节点数,将其依次从队列中弹出,然后加入这一行的一维数组中,如果它们有子节点,依次加入队列排队等待访问。
  • step 5:访问完这一层的元素后,将这个一维数组加入二维数组中,再访问下一层。

        代码:

import java.util.*;
public class Solution {
    public ArrayList<ArrayList<Integer>> levelOrder (TreeNode root) {
        //保存遍历结果的二维数组
        ArrayList<ArrayList<Integer>> res = new ArrayList<>();
        //判断树是否为空
        if(root == null){
            return res;
        }
        //节点存储队列
        Queue<TreeNode> queue = new ArrayDeque<TreeNode>();
        //将根节点提前加入队列
        queue.add(root);
        //遍历树
        while(!queue.isEmpty()){
            //记录每一层元素的一维数组
            ArrayList<Integer> col = new ArrayList<>();
            //记录此层的节点个数
            int n = queue.size();
            //遍历此层的节点
            for(int i = 0; i < n; i ++){
                //将节点出队列
                TreeNode tmp = queue.poll();
                //将节点值加入一维数组
                col.add(tmp.val);
                //将节点的子节点入队列
                if(tmp.left != null){
                    queue.add(tmp.left);
                }
                if(tmp.right != null){
                    queue.add(tmp.right);
                }
            }
            //将每一层的元素组成的一维数组加入二维数组
            res.add(col);
        }
        return res;
    }
}

          复杂度分析:

  • 时间复杂度:O(n),其中n为二叉树的节点数,每个节点访问一次
  • 空间复杂度:O(n),队列的空间为二叉树的一层的节点数,最坏情况二叉树的一层为O(n)级

        2、递归

        按行遍历的关键是每一行的深度对应了它输出在二维数组中的深度,即深度可以与二维数组的下标对应,那我们可以在递归的访问每个节点的时候记录深度,进入子节点则深度加1,每个节点值放入二维数组相应行。

        因此可以用递归实现:

  • 终止条件: 遍历到了空节点,就不再继续,返回。
  • 返回值: 将加入的输出数组中的结果往上返回。
  • 本级任务: 处理按照上述思路处理非空节点,并进入该节点的子节点作为子问题。

        具体做法:

  • step 1:首先判断二叉树是否为空,空树没有遍历结果。
  • step 2:使用递归进行层次遍历输出,每次递归记录当前二叉树的深度,每当遍历到一个节点,如果为空直接返回。
  • step 3:如果遍历的节点不为空,输出二维数组中一维数组的个数(即代表了输出的行数)小于深度,说明这个节点应该是新的一层,我们在二维数组中增加一个一维数组,然后再加入二叉树元素。
  • step 4:如果不是step 3的情况说明这个深度我们已经有了数组,直接根据深度作为下标取出数组,将元素加在最后就可以了。
  • step 5:处理完这个节点,再依次递归进入左右节点,同时深度增加。因为我们进入递归的时候是先左后右,那么遍历的时候也是先左后右,正好是层次遍历的顺序。

        代码:

import java.util.*;
public class Solution {
    //记录输出
    ArrayList<ArrayList<Integer> > res = new ArrayList(); 
    void traverse(TreeNode root, int depth) {
        if(root != null){
            //新的一层
            if(res.size() < depth){  
                ArrayList<Integer> row = new ArrayList(); 
                res.add(row);
                row.add(root.val);
            //读取该层的一维数组,将元素加入末尾
            }else{ 
                ArrayList<Integer> row = res.get(depth - 1);
                row.add(root.val);
            }
        }
        else
            return;
        //递归左右时深度记得加1
        traverse(root.left, depth + 1); 
        traverse(root.right, depth + 1);
    }
    public ArrayList<ArrayList<Integer>> levelOrder (TreeNode root) {
        if(root == null)
            //如果是空,则直接返回
            return res; 
        //递归层次遍历 
        traverse(root, 1); 
        return res;
    }
}

        复杂度分析:

  • 时间复杂度:O(n),其中n为二叉树的节点数,每个节点访问一次
  • 空间复杂度:O(n),最坏二叉树退化为链表,递归栈的最大深度为n

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值