树的广度优先搜索BFS

1. 基本思想

思路:输出与当前节点直接相连的节点,直至将与之相连的节点全部输出完,则进入下一层,直至全部节点都被遍历一遍。

Java Bfs模版 java bfs算法_二叉树


如图所示有一颗二叉树,根节点为A。输出其广度优先搜索的值。

第一步:将A输出,此时输出为A;
第二步:将A的左孩子输出,此时输出为A B;再将A的右孩子输出,此时输出为A BC;
第三步:此时输出为A BC,而A已经输出了,那么便输出B的左右孩子,此时输出为A BC DE;再输出C的左右孩子,此时输出为A BC DEFG。
第四步:再输出D的左右孩子,发现为空;
第五步:再输出E的左右孩子,发现为空;
第六步:再输出F的左右孩子,发现为空;
第七步:再输出G的左右孩子,发现为空。遍历结束,输出为ABCDEF。

2.代码实现可能需要的数据结构(JAVA)

2.1 顺序队列

特点:先进先出

常用操作:

  1. 定义一个队列(<>内的数据类型根据需要有Character、Sting、Integer等)
    Queue< Character >queue = new LinkedList< Charccter >();
  2. queue.offer():在队尾添加一个元素;
  3. queue.poll():移除队首元素并返回该元素;
  4. queue.peek():返回队首元素,不移除;
  5. queue.isEmpty():判断队列是否为空,是则返回true,否则返回false。

2.2 哈希表

常用操作:

  1. 定义一个哈希表
    Map< Integer,Integer > hashtable = new HashMap< Integer. Integer >();;
  2. put(key,value):向哈希表中加入一对新的键值对;
  3. get(key):通过关键字取其值;
  4. remove(key):根据关键字删除键值对;
  5. isEmpty():查看哈希表是否为空;
  6. containsKey(key):判断哈希表中是否存在关键字key。

3. 将基本思想转换为代码思想

  1. 给每个节点设置一个flag值,用于判断当前节点是否已经输出。flag=1表示已输出,flag=0表示未输出。每个节点的flag值可以用键值对实现;
  2. 数据结构使用队列queue,特点是先进先出,符合BFS的思想;
  3. 首先将根节点入队(队里的第一个节点);
  4. 将根节点出队(输出),与根节点相邻的所有节点入队;
  5. 队首出队,将该节点的所有节点加入队列;
  6. 重复操作5,直至全部输出。

4.转换成代码(JAVA实现,仅供思路参考)

public String bfs(TreeNode root){
    if(root == null) return '';
    Queue<TreeNode> queue = new LinkedList<TreeNode>();
    Map<TreeNode,Character> hashmap = new HashMap<TreeNode,Character>();
    String string = '';
    queue.offer(root);
    while(!queue.isEmpty()){
        TreeNode node = queue.poll();
        hashmap.put(root,1);
        if(node.left!=null&&hashmap.get(node.left)!=1) queue.offer(node.left);
        if(node.right!=null&&hashmap.get(node.right)!=1) queue.offer(node.right);
        string = string + node.val;
    }
    return string;
}

5.实例

Java Bfs模版 java bfs算法_java_02

class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        if(root == null) return new ArrayList<>();
		// res为最终返回的结果
        List<List<Integer>> res = new ArrayList<>();
        // 新建队列
        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        // 根节点入队
        queue.offer(root);
        // 如果队列非空
        while(!queue.isEmpty()){
        	// 用count来控制每一层的节点输出
            int count = queue.size();
            // 用list来进行每层的输出
            List<Integer> list = new ArrayList<Integer>();
            while(count>0){
            	// 队首出队
                TreeNode node = queue.poll();
                // 队首出队入列
                list.add(node.val);
                // 左孩子入队
                if(node.left != null) queue.offer(node.left);
                // 右孩子入队
                if(node.right != null) queue.offer(node.right);
                // 出队后该层数量减1
                count--;
            }
            // 将该层加到最终输出的值中
            res.add(list);
        }
        // 返回最终输出值res
        return res;
    }
}