图搜索算法

图搜索算法

用于解决最短路径、所有路径、是否连通等问题;

图搜索算法需要考虑的情况: 1、根据是否存在权重,选择计算最短的指标; 2、如果存在环,需要增加==访问记录==,以此跳过访问过的节点;

DFS和BFS的选择

DFS适用于:

  • 求解所有路径;
  • 找到一条路径;(某两个顶点是否连通) BFS适用于:
  • 求解所有路径;
  • 找到一条路径;(某两个顶点是否连通)
  • ==搜索最短路径==;
  • ==构建最小生成树==;

DFS

优势: 1、占用内存空间少;只需要存储当前路径节点; 2、不适合最短路径问题; 3、可以进行回溯;

适用问题: 1、求解所有路径、找到一条路径(某两个顶点是否连通);

模板: 1、通常使用递归的方式;(如果是二叉树可以前序遍历)

public void DFS(TreeNode root) {
    if (root == null)
        return;

    //在这里处理遍历到的TreeNode节点
    DFS(root.left);
    DFS(root.right);
}

2、栈实现;

public void DFSWithStack(TreeNode root) {
     if (root != null)
         return;
     Stack<TreeNode> stack = new Stack<>();
     stack.push(root);

     while (!stack.isEmpty()) {
         TreeNode treeNode = stack.pop();

         //在这里处理遍历到的TreeNode

         if (treeNode.right != null)
             stack.push(treeNode.right);
         if (treeNode.left != null)
             stack.push(treeNode.left);
     }
}

3、二维数组DFS(岛屿问题)

private int[] dx = new int[]{0, 1, -1, 0};
private int[] dy = new int[]{1, 0, 0, -1};

private void dfs(char[][] grid, int x, int y) {
    // 边界
    if (x >= grid.length || y >= grid[0].length || x < 0 || y < 0) {
        return;
    }
    
    // 需要处理的逻辑

    for (int j = 0; j < 4; j++) {
        // 分别探索四个方向
        dfs(grid, x + dx[j], y + dy[j]);
    }
}

BFS

特点: 1、能够找到最近的节点,DFS不擅长; 2、占用空间更大,需要存储整个图;

适用问题: 1、求解所有路径、找到一条路径(某两个顶点是否连通); 2、==最短路径问题==;

  • 如果无权图,则可以找到第一个路径就停止;
  • 如果有权图,则需要==优先队列==,队列内保持权重排序,每次优先寻找最小权重节点;但是仍然需要遍历能够到达终点的所有可能情况,选择最短的路径;

模板: 1、通常需要一个队列,保存将要访问的节点;

public void BFSWithQueue(TreeNode root) { 
	Deque<TreeNode> queue = new ArrayDeque<>(); 
	
	if (root != null) 
		queue.add(root); 
		
	while (!queue.isEmpty()) {
		TreeNode treeNode = queue.poll(); 
		
		//在这里处理遍历到的TreeNode节点 
		
		if (treeNode.left != null) 
			queue.add(treeNode.left); 
		if (treeNode.right != null) 
			queue.add(treeNode.right); 
	} 
}