1、深度优先搜索DFS(Deep First Search)
偏向于体现目标明确时的到达路径,运用栈
(1)向一个方向递归下去
(2)未找到且碰到边界,回溯
(3)向下一个方向继续递归下去
(4)反复,直到找到
起点(0,0),终点(3,3),passed 记录路径:
0 0 0 0
1 0 0 0
1 0 0 0
1 0 0 1
1 1 1 1
2、广度优先搜索BFS(Breadth First Search)
偏向于体现大范围的扫描寻找并记录各个点的到达步数,运用队列
(1)由起点向四个方向分别扫描下一个点,依次记录点到队列里
(2)出队一个点,继续(1)
(3)反复,直到找到
起点(0,0),终点(3,3),passed 记录路径:
1 2 3 4
2 3 4 5
3 4 5 6
4 5 6 7
5 6 7 0
【基础实现】
import org.junit.Test;
import java.util.LinkedList;
import java.util.Queue;
public class DfsBfs {
int row = 5, column = 4;
//地图
int[][] graph = new int[row][column];
//记录地图上的点是否走过
int[][] passed = new int[row][column];
//起点坐标
int startX = 0, startY = 0;
//目标坐标
int targetX = 3, targetY = 3;
//下右上左移动
int[] moveX = {1, 0, -1, 0};
int[] moveY = {0, 1, 0, -1};
boolean flag = false;
public void dfs(int[][] graph, int[][] passed, int startX, int startY) {
if (startX == targetX && startY == targetY) {
flag = true;
return;
}
//尝试向下右上左移动
for (int i = 0; i < 4; i++) {
//移动后坐标
int newX = startX + moveX[i];
int newY = startY + moveY[i];
//越界或走过
if (newX < 0 || newX >= graph.length || newY < 0 || newY >= graph[0].length || passed[newX][newY] == 1) {
continue;
}
passed[newX][newY] = 1;
//继续搜索
dfs(graph, passed, newX, newY);
if (flag) {
break;
}
//回溯
passed[newX][newY] = 0;
}
}
@Test
public void useDfs() {
dfs(graph, passed, startX, startY);
}
public void bfs(int[][] graph, int[][] passed, int startX, int startY) {
Queue<Node> queue = new LinkedList<>();
//若默认为0,扫描时passed[newX][newY] > 0是false,会被认为是没扫描的点
passed[startX][startY] = 1;
//起点入队
queue.offer(new Node(startX, startY, 1));
while (!queue.isEmpty()) {
Node curNode = queue.poll();
//尝试向下右上左扫描
for (int i = 0; i < 4; i++) {
//移动后坐标
int newX = curNode.x + moveX[i];
int newY = curNode.y + moveY[i];
//越界
if (newX < 0 || newX >= graph.length || newY < 0 || newY >= graph[0].length || passed[newX][newY] > 0) {
continue;
}
//记录步数
passed[newX][newY] = curNode.step + 1;
//记录状态
queue.offer(new Node(newX, newY, curNode.step + 1));
if (newX == targetX && newY == targetY){
flag = true;
break;
}
}
if (flag){
break;
}
}
}
//外部类(DfsBfs)未实例化时静态内部类也能实例化,不依赖外部类(DfsBfs),没有强耦合和相互作用,节约资源
private static class Node {
int x;
int y;
int step;
public Node(int x, int y, int step) {
this.x = x;
this.y = y;
this.step = step;
}
}
@Test
public void useBfs() {
bfs(graph, passed, startX, startY);
System.out.println();
}
}
参考:
https://zhuanlan.zhihu.com/p/24986203
https://www.imooc.com/article/17187