二叉树广度优先搜索遍历(BFS)

解决二叉树中广度优先搜索遍历的主要思路:

借助于队列

基础的BFS结构实现

void bfs(TreeNode root) {
    Queue<TreeNode> queue = new ArrayDeque<>();
    queue.add(root);
    while (!queue.isEmpty()) {
        TreeNode node = queue.poll(); // Java 的 pop 写作 poll()
        if (node.left != null) {
            queue.add(node.left);
        }
        if (node.right != null) {
            queue.add(node.right);
        }
    }
}

二叉树中BFS使用的两个主要场景

层序遍历

二叉树的层序遍历(从上到下)

题目描述
在这里插入图片描述

private static List<List<Integer>> levelOrderTraversal(TreeNode root) {
        ArrayList<List<Integer>> res = new ArrayList<>();
        // 层序遍历要求的输出结果和 BFS的输出结果是不同的。
        // 层序遍历要求我们区分每一层,也就是返回一个二维数组 -> [[1], [2, 3], [4, 5]]。
        // 而 BFS 的遍历结果是一个一维数组,无法区分每一层 -> [1, 2, 3, 4, 5]
        if (root == null){
            return res;
        }

        Queue<TreeNode> queue = new LinkedList<>();
        // Queue 中 add() 和 offer()都是用来向队列添加一个元素。
        // 在容量已满的情况下,add() 方法会抛出IllegalStateException异常,offer() 方法只会返回 false 。
        queue.offer(root);  // 向队列中添加元素

        while (!queue.isEmpty()){
            // 定义一个列表,存储每一层节点的值
            List<Integer> levelRes = new ArrayList<>();
            
            // 在开始遍历每一层的节点之前,先记录队列中节点的个数
            int currentLevelSize = queue.size();
            
            // 遍历当前层,获取当前层的所有的节点的val
            for (int i = 0; i < currentLevelSize; i++) {
                TreeNode node = queue.poll();
                levelRes.add(node.val);
                
                // 在获取当前层的节点的值的过程中,将下一层所有的节点加入到队列中
                if (node.left != null){
                    queue.offer(node.left);
                }
                if (node.right != null){
                    queue.offer(node.right);
                }
            }
            res.add(levelRes);
        }
        return res;
    }
二叉树的层序遍历(从下向上)

题目描述
在这里插入图片描述

    private static List<List<Integer>> ReverseLevelOrderTraversal(TreeNode root) {
        // 相比于自上向下的层序遍历,这道题要求从下到上输出每一层的节点值。
        // 只要对上述上一个题解的操作稍作修改即可:在遍历完一层节点之后,将存储该层节点值的列表添加到结果列表的头部。
        // 为了降低在结果列表的头部添加一层节点值的列表的时间复杂度,这里就要求,存储结果的二维数组需要是链表的结构。
        List<List<Integer>> res = new LinkedList<>();

        if (root == null){
            return res;
        }

        // 定义一个队列  用于存储每一层的节点
        Queue<TreeNode> queue = new LinkedList<>();
        
        // 将头结点(第一层的节点)加入到队列中
        queue.offer(root);

        while (!queue.isEmpty()){
            // 创建一个存储结果的列表,为了降低时间复杂度,这里的列表使用链式结构
            List<Integer> levelRes = new ArrayList<>();

            // 获取当前层中节点个数
            int currentLevelSize = queue.size();
            for (int i = 0; i < currentLevelSize; i++) {
                // 出队一个节点
                TreeNode node = queue.poll();
                levelRes.add(node.val);

                if (node.left != null){
                    queue.offer(node.left);
                }

                if (node.right != null){
                    queue.offer(node.right);
                }

            }
            // 将存储当前层节点值的列表添加到结果列表的头部
            res.add(0, levelRes);
        }

        return res;
    }
二叉树的右视图

题目描述
在这里插入图片描述

private static List<Integer> rightSideView(TreeNode root) {
        // 创建一个返回结果集合
        List<Integer> resList = new ArrayList<>();

        if (root == null) {
            return resList;
        }

        // 创建队列  用来存放节点
        Queue<TreeNode> queue = new LinkedList<>();
        // 将头结点放入到队列中
        queue.offer(root);

        while (!queue.isEmpty()) {

            // 获取当前层的长度
            int currentLevelLength = queue.size();

            // 遍历当前层,将下一层的所有节点放入到队列中,并且将当前层最后一个节点值加入到返回结果集中
            for (int i = 0; i < currentLevelLength; i++) {
                // 取出节点
                TreeNode node = queue.poll();
                if (i == currentLevelLength - 1){
                    resList.add(node.val);
                }
                if (node.left != null){
                    queue.offer(node.left);
                }

                if (node.right != null){
                    queue.offer(node.right);
                }
            }
        }
        return resList;
    }

最短路径

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值