广度优先搜索入门
来源:互联网 发布:linux中ftp配置 编辑:程序博客网 时间:2024/05/29 15:12
简介:
广度优先搜索(Breadth-first-search),又称宽度优先搜索,简称 bfs,是图的搜索算法之一。与深度优先搜索不同的是,广度优先搜索会先搜索到与起始点距离较近的点,而深搜却是沿着一个分支递归到最后。
对上图进行深搜按照节点访问顺序会得到序列:A−B−E−F−C−D−G
对上图进行宽搜按照节点访问顺序会得到序列:A−B−C−D−E−F−G
宽搜可以理解为,从起点开始一层一层地往外扩展,内层一定会在外层前面被访问到。
与深度优先搜索的对比
深度优先搜索用栈(stack)来实现:
- 把起始节点压入栈中。
- 每次从栈顶元素,搜索所有在它下一级的元素,把这些元素压入栈中。(若回溯,栈顶也将弹出。)
- 找到所要找的元素时结束程序。
广度优先搜索使用队列(queue)来实现:
- 把起始节点放到队列中。
- 每次从队列的头部取出一个元素,查看这个元素所有的下一级元素,把它们放到队列的末尾。(查看完毕以后,头部元素弹出,即队首指针右移。)
- 找到所要找的元素时结束程序。
bfs 的一般写法
void bfs(起始点){ 将起始点放入队列中; while(如果队列不为空){ 访问队列中队首元素x; 删除队首元素; for (x 可以到达的所有点){ if(该点未被访问过且合法){ 将该点加入队列末尾; } } } 队列为空,宽搜结束;}
迷宫问题
相信大家都玩过走迷宫。用 2 维数组来表示一个迷宫- S##.
- . . . .
- ###T
‘S’表示起点,‘T’表示终点,‘#’表示墙壁,‘ . ‘表示平地。你需要从‘S’出发走到‘T’,每次只能上下左右走动,并且不能走出地图,也不能走进墙壁,每个点只能通过一次。现在要求你求出有多少种走的方案。
现在需要求解最少步数,我们依然可以用深搜来遍历所有可能性,然后从中选取最优的步数。但是宽搜则不需要搜索所有的路径,因为它的层数是由小到大的特点,它的步数一定是最少的,也就是最优解。所以在这一类问题上,宽搜比深搜更有优势。
实现代码
import java.util.LinkedList;import java.util.Queue;import java.util.Scanner;class Node{int x;int y;int step;Node(int x,int y,int step){this.x = x;this.y = y;this.step = step;}}public class Main {static int next[][] = {{1,0},{-1,0},{0,1},{0,-1}}; //4个方向static int n,m;static int box[][] = new int [100+10][100+10];static char map[][] = new char[100+10][100+10];public static void main(String[] args) {Scanner cin = new Scanner(System.in);n = cin.nextInt(); m = cin.nextInt();String s = "";int startx = 0, starty = 0;for (int i = 0; i < n; i++) {s = cin.next();for (int j = 0; j <m; j++) {map[i][j] = s.charAt(j);if(map[i][j] == 'S'){startx = i; starty =j;}}//初始化}if(bfs(startx,starty)<0){System.out.println(-1);}}static int bfs(int x,int y){Queue<Node> q = new LinkedList<Node>();q.offer(new Node(x, y,0)); //将起点放入队列中box[x][y] = 1;//该点访问过了while(!q.isEmpty()){Node head = q.poll();//取出队头 进行下面操作int next_x = 0; int next_y = 0;for (int i = 0; i <next.length; i++) {next_x = head.x+next[i][0];next_y = head.y+next[i][1];if(next_x<0||next_y<0||next_x>=n||next_y>=m)continue;if(map[next_x][next_y] == 'T'){System.out.println(head.step+1);return 0;}if(box[next_x][next_y] == 0 && map[next_x][next_y] != '#'){box[next_x][next_y] = 1;Node newNode = new Node(next_x, next_y,head.step+1);q.offer(newNode);}}}return -1;}}
一维坐标的移动
在一个长度为 n 的坐标轴上,小明想从 A点 移动到 B 点。他的移动规则如下:
- 向前一步,坐标增加 1。
- 向后一步,坐标减少 1。
- 跳跃一步,使得坐标乘 2。
小明不能移动到坐标小于 0 或大于 n 的位置。小明想知道从 A 点移动到 B 点的最少步数是多少,你能帮他计算出来么?
输入格式
第一行输入三个整数 n,A,B,分别代表坐标轴长度,起始点坐标,终点坐标。(0≤A,B≤n≤5000)
输出格式
输出一个整数占一行,代表小明要走的最少步数。
样例输入
10 2 7
样例输出
3
实现代码
import java.util.LinkedList;import java.util.Queue;import java.util.Scanner;class Point{int x;int step;Point(int x,int step){this.x = x;this.step = step;}}public class Main {static void bfs(int x){Queue<Point> q = new LinkedList<Point>();q.offer(new Point(x,0));box[x] = 1;while(!q.isEmpty()){Point head = q.poll();for (int i = 1; i <=3; i++) {int next_x = 0;if(i==1){next_x = head.x+1;}else if(i==2){next_x = head.x-1;}else{next_x = head.x*2;}if(next_x<0||next_x>n) continue;if(next_x == B){System.out.println(head.step+1);return;}if(box[next_x] == 0){box[next_x] = 1;Point newpoint = new Point(next_x,head.step+1);q.offer(newpoint);}}}}static int n, A, B;static int box[] = new int [5000+5];public static void main(String[] args) {Scanner cin = new Scanner(System.in);n = cin.nextInt(); A = cin.nextInt(); B = cin.nextInt();bfs(A);}}
阅读全文
0 0
- 广度优先搜索入门
- 广度优先搜索入门
- 广度优先搜索 入门题
- 广度优先搜索(入门)
- 【算法入门】广度/宽度优先搜索(BFS)
- 【算法入门】广度/宽度优先搜索(BFS)
- 【算法入门】广度/宽度优先搜索(BFS)
- 【算法入门】广度/宽度优先搜索(BFS)
- 【算法入门】广度/宽度优先搜索(BFS)
- 【算法入门】广度/宽度优先搜索(BFS)
- BFS广度优先搜索——入门
- 【算法入门】广度优先搜索(BFS)
- 【算法入门】广度/宽度优先搜索(DFS)
- 【算法入门】广度/宽度优先搜索(BFS)
- 【算法入门】广度/宽度优先搜索(BFS)
- 【算法入门】广度/宽度优先搜索(BFS)
- 广度优先搜索算法
- 双向广度优先搜索
- linux下ffmpeg安装记录
- web.xml配置
- 页面滚动到一定的距离时,导航条绝对定位
- PAT A1121. Damn Single (25)
- 谈谈对PureMVC的理解
- 广度优先搜索入门
- 线性回归
- CSS——后代选择器
- LintCode permutations(全排列)
- Lucene学习总结之七:Lucene搜索过程解析(1)
- springmvc+shiro+maven 实现登录认证与权限授权管理
- Git for windows 码云
- android按键监听事件
- SQL中调用存储过程