Breadth First Search,广度优先搜索。
一般用于找最短路径,时间复杂度较低,代价是空间复杂度高。
框架
想象为一棵树从根节点到全部第二节点再到全部第三节点最后到全部根节点遍历。
// 计算从起点 start 到终点 target 的最近距离int BFS(Node start, Node target) {Queue<Node> q; // 核心数据结构Set<Node> visited; // 避免走回头路q.offer(start); // 将起点加入队列visited.add(start);int step = 0; // 记录扩散的步数while (q not empty) {int sz = q.size();/* 将当前队列中的所有节点向四周扩散 */for (int i = 0; i < sz; i++) {Node cur = q.poll();/* 划重点:这里判断是否到达终点 */if (cur is target)return step;/* 将 cur 的相邻节点加入队列 */for (Node x : cur.adj())if (x not in visited) {q.offer(x);visited.add(x);}}/* 划重点:更新步数在这里 */step++;}}
队列 q 就不说了,BFS 的核心数据结构;cur.adj() 泛指 cur 相邻的节点,比如说二维数组中,cur 上下左右四面的位置就是相邻节点;visited 的主要作用是防止走回头路,大部分时候都是必须的,但是像一般的二叉树结构,没有子节点到父节点的指针,不会走回头路就不需要 visited。
二叉树的最小高度
Leetcode-简单
套用上面的框架,start 起点就是根节点root ,重点 target 就是最靠近根节点的叶子节点,也就是叶子节点的两个子节点都为null。
表达式为:
if (no.left == null && no.right == null) {return dep;}
代码:
public class BFSdemo {static int bfs(TreeNode root) {if (root == null) {return 0;}//队列,存储当前层级所有节点Queue<TreeNode> queue = new LinkedList<>();queue.add(root);int dep = 1;while (!queue.isEmpty()) {//当前队列大小必须独立常量出来,否则queue.size()的数值不断变化,for循环出错。int size = queue.size();for (int i = 0; i < size; i++) {//获得队列第一个值并移除TreeNode cur = queue.poll();//结束条件if (cur.left == null && cur.right == null) {return dep;}//将cur节点的子节点加入队列if (cur.left != null) {queue.offer(cur.left);}if (cur.right != null) {queue.offer(cur.right);}}dep++;}return dep;}//[3,9,20,null,null,15,7]public static void main(String[] args) {TreeNode root = new TreeNode(3);root.left = new TreeNode(9);root.right = new TreeNode(20);root.right.left = new TreeNode(15);root.right.right = new TreeNode(7);int dep = bfs(root);System.out.println(dep);}}public class TreeNode {public int val;public TreeNode left;public TreeNode right;public TreeNode() {}public TreeNode(int val) { this.val = val; }public TreeNode(int val, TreeNode left, TreeNode right) {this.val = val;this.left = left;this.right = right;}}
