宽度优先搜索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;
}
}