宽度优先搜索BFS的三种实现方法(单队列,双队列,哨兵)——二叉树的层序遍历102

宽度优先搜索

题目:二叉树的层序遍历

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

输入:[3,9,20,null,null,15,7]

    3
   / \
  9  20
    /  \
   15   7

输出:[[3],[9,20],[15,7]]

 

思路:利用BFS遍历二叉树,输出每层遍历的值

1.单队列

非递归实现:

class Solution {
        public List<List<Integer>> levelOrder(TreeNode root) {
            List<List<Integer>> res = new ArrayList<>();
            if (root == null) return res;

            Queue<TreeNode> queue = new LinkedList<>();
            queue.add(root);

            while (!queue.isEmpty()) {
                int length = queue.size();
                List<Integer> list = new ArrayList<>();

                for (int i = 0; i < length; i++) {
                    TreeNode temp = queue.poll();
                    list.add(temp.val);

                    if (temp.left != null)
                        queue.add(temp.left);
                    if (temp.right != null)
                        queue.add(temp.right);
                }
                res.add(list);
            }

            return res;
        }
    }

递归实现:

class Solution {
        private List<List<Integer>> res;

        public void bfs(Queue<TreeNode> queue) {
            if (queue.isEmpty()) return;

            List<Integer> list = new ArrayList<>();
            int length = queue.size();

            for (int i = 0; i < length; i++) {
                TreeNode temp = queue.poll();
                list.add(temp.val);

                if (temp.left != null)
                    queue.add(temp.left);
                if (temp.right != null)
                    queue.add(temp.right);
            }
            res.add(list);
            bfs(queue);
        }

        public List<List<Integer>> levelOrder(TreeNode root) {
            res = new ArrayList<>();
            if (root == null) return res;

            Queue<TreeNode> queue = new LinkedList<>();
            queue.add(root);
            bfs(queue);

            return res;
        }
    }

2. 双队列

  用两个队列轮次存储当前节点和下层节点。

class Solution {
        public List<List<Integer>> levelOrder(TreeNode root) {
            List<List<Integer>> res = new ArrayList<>();
            if (root == null) return res;

            List<TreeNode> queue = new ArrayList<>();
            queue.add(root);

            while (!queue.isEmpty()) {
                List<TreeNode> queue2 = new ArrayList<>();
                List<Integer> level = new ArrayList<>();

                for (TreeNode node : queue) {
                    level.add(node.val);
                    if (node.left != null)
                        queue2.add(node.left);
                    if (node.right != null)
                        queue2.add(node.right);
                }
                res.add(level);
                queue = queue2;
            }
            return res;
        }
    }

3. 哨兵

哨兵:头节点之前的空节点,始终指向头结点。

在队列中,在每一层后加一个空的节点,用来区别不同的层。遍历每一层时,如果当前队列的为null时,则在队列末尾即下一层添加一个null。

class Solution {
        public List<List<Integer>> levelOrder(TreeNode root) {
            List<List<Integer>> res = new ArrayList<>();
            if (root == null) return res;

            Queue<TreeNode> queue = new LinkedList<>();
            queue.add(root);
            queue.add(null);

            List<Integer> level = new ArrayList<>();
            while (!queue.isEmpty()) {
                TreeNode temp = queue.poll();
                if (null == temp) {
                    res.add(level);
                    if (queue.isEmpty())
                        break;

                    queue.add(null);
                    level = new ArrayList<>();
                    continue;
                }

                level.add(temp.val);
                if (temp.left != null)
                    queue.add(temp.left);
                if (temp.right != null)
                    queue.add(temp.right);
            }
            return res;
        }
    }

 

posted @ 2021-12-12 16:52  言思宁  阅读(147)  评论(0编辑  收藏  举报