package myalgorithm;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
/*BFS用于记录的位置和值的结构*/
class node
{
node(int xparam,int yparam,int valparam)
{
this.x = xparam;
this.y = yparam;
this.value = valparam;
}
int x,y,value;
}
public class ShortPath {
/*全局最短路径*/
public int stepnum = 999;
/*构建11*11的迷宫,英雄H在(1,1)的位置出发,去解救美女M(6,8)*/
char[][] graph = {
{'#','#','#','#','#','#','#','#','#','#','#'},
{'#','H','_','_','*','_','_','*','_','_','#'},
{'#','_','_','_','_','_','_','_','_','_','#'},
{'#','_','*','_','_','_','*','_','_','_','#'},
{'#','_','_','_','*','_','_','_','_','*','#'},
{'#','_','_','_','_','_','_','*','_','*','#'},
{'#','_','*','_','_','_','_','_','M','_','#'},
{'#','*','_','_','*','_','_','_','_','_','#'},
{'#','_','_','_','_','_','_','_','_','_','#'},
{'#','_','_','_','*','_','_','_','_','_','#'},
{'#','#','#','#','#','#','#','#','#','#','#'},
};
/*初始标记数组都为0*/
public int[][] mark = new int[graph.length][graph.length];
/*每一个位置有四种选择:右下左上*/
public int[][] choose = {
{0,1},
{1,0},
{0,-1},
{-1,0}
};
/*BFS算法*/
public void BFS(node startPoint)
{
//起始点装入队列
Queue<node> queue = new LinkedList<node>();
startPoint.value = 1;//确保起始步数为1
queue.offer(startPoint); node t1;
int tx,ty;
top:
while(!queue.isEmpty())
{
//取队首,出队后不再入队,value也自此固定
t1 = queue.poll();
mark[t1.x][t1.y] = t1.value;//标记步数
for(int i=0;i<4;i++)
{
tx = t1.x + choose[i][0];
ty = t1.y + choose[i][1]; //找到美女,肯定是最短的,可以立即返回
if(graph[tx][ty] == 'M')
{
stepnum = t1.value + 1;//下一步可到
mark[tx][ty] = stepnum;
break top;
}
//继续接着找,把空路径添加到队列末尾
//不是炸弹和围墙,并且没有被标记
if(graph[tx][ty] != '#'
&& graph[tx][ty] != '*'
&&mark[tx][ty] == 0)
{
queue.offer(new node(tx,ty,t1.value+1));
}
}
}
}
/*BFS回溯路径*/
private void getPath(node target) { int beforex = 0,beforey = 0;
int x = target.x;
int y = target.y;
for(int i=0;i<4;i++)
{
beforex = x + choose[i][0];
beforey = y + choose[i][1];
//找到英雄的出发点,函数结束
if (beforex == 1 && beforey == 1)
{
return;
}
if(mark[x][y] - 1 == mark[beforex][beforey])
{
System.out.print("("+beforex+","+beforey+")<--");
break;
}
}
getPath(new node(beforex,beforey,0));
return;
}
/*main函数*/
public static void main(String[] args) {
ShortPath my = new ShortPath(); long start = System.currentTimeMillis();
my.BFS(new node(1,1,0));
long end = System.currentTimeMillis();
System.out.println("BFS step: " + my.stepnum + " time:" + (end-start));
//打印标记结果
for (int m = 0;m<my.graph.length;m++)
System.out.println(Arrays.toString(my.mark[m]));
//打印巡回路径
my.getPath(new node(6,8,0));
} }

BFS step: 13 time:4
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 1, 2, 3, 0, 7, 8, 0, 10, 11, 0]
[0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0]
[0, 3, 0, 5, 6, 7, 0, 9, 10, 11, 0]
[0, 4, 5, 6, 0, 8, 9, 10, 11, 0, 0]
[0, 5, 6, 7, 8, 9, 10, 0, 12, 0, 0]
[0, 6, 0, 8, 9, 10, 11, 0, 13, 0, 0]
[0, 0, 10, 9, 0, 11, 0, 0, 0, 0, 0]
[0, 0, 11, 10, 11, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
(5,8)<--(4,8)<--(4,7)<--(4,6)<--(4,5)<--(3,5)<--(3,4)<--(3,3)<--(2,3)<--(2,2)<--(2,1)


扩展:

PhotoShop中的魔术棒选择工具的原理,就是从鼠标选中的点作为种子,并加入队列;依次查找周边的点,如果颜色与种子颜色相近,则加入队列;对队列中的元素依次进行类似扩展,这样就选取了与最初种子颜色相同的点的集合。

广度优先算法BFS的更多相关文章

  1. 广度优先算法(BFS)与深度优先算法(DFS)

    一.广度优先算法BFS(Breadth First Search) 基本实现思想 (1)顶点v入队列. (2)当队列非空时则继续执行,否则算法结束. (3)出队列取得队头顶点v: (4)查找顶点v的所 ...

  2. 图的遍历(搜索)算法(深度优先算法DFS和广度优先算法BFS)

    图的遍历的定义: 从图的某个顶点出发访问遍图中所有顶点,且每个顶点仅被访问一次.(连通图与非连通图) 深度优先遍历(DFS): 1.访问指定的起始顶点: 2.若当前访问的顶点的邻接顶点有未被访问的,则 ...

  3. [ACM训练] 算法初级 之 搜索算法 之 广度优先算法BFS (POJ 3278+1426+3126+3087+3414)

    BFS算法与树的层次遍历很像,具有明显的层次性,一般都是使用队列来实现的!!! 常用步骤: 1.设置访问标记int visited[N],要覆盖所有的可能访问数据个数,这里设置成int而不是bool, ...

  4. 图的深度优先搜索(DFS)和广度优先搜索(BFS)算法

    深度优先(DFS) 深度优先遍历,从初始访问结点出发,我们知道初始访问结点可能有多个邻接结点,深度优先遍历的策略就是首先访问第一个邻接结点,然后再以这个被访问的邻接结点作为初始结点,访问它的第一个邻接 ...

  5. 【数据结构与算法Python版学习笔记】图——词梯问题 广度优先搜索 BFS

    词梯Word Ladder问题 要求是相邻两个单词之间差异只能是1个字母,如FOOL变SAGE: FOOL >> POOL >> POLL >> POLE > ...

  6. 广度优先遍历-BFS、深度优先遍历-DFS

    广度优先遍历-BFS 广度优先遍历类似与二叉树的层序遍历算法,它的基本思想是:首先访问起始顶点v,接着由v出发,依次访问v的各个未访问的顶点w1 w2 w3....wn,然后再依次访问w1 w2 w3 ...

  7. 聊聊算法——BFS和DFS

    如果面试字节跳动和腾讯,上来就是先撕算法,阿里就是会突然给你电话,而且不太在意是周末还是深夜, 别问我怎么知道的,想确认的可以亲自去试试.说到算法,直接力扣hard三百题也是可以的,但似乎会比较伤脑, ...

  8. 广度优先搜索 BFS 学习笔记

    广度优先搜索 BFS 学习笔记 引入 广搜是图论中的基础算法之一,属于一种盲目搜寻方法. 广搜需要使用队列来实现,分以下几步: 将起点插入队尾: 取队首 \(u\),如果 $u\to v $ 有一条路 ...

  9. C语言之广度优先算法

    广度优先算法又称宽度优先搜索,是一种简便的图的搜索算法之一.搜索方式大致是这样的: 直到搜索到目标结点(结点就是那些圆球球,其中有一个或者多个是目标结点)或者搜完了整个图都没找到目标结点就停止搜索. ...

随机推荐

  1. iOS开发——语法篇OC篇&高级语法精讲二

    Objective高级语法精讲二 Objective-C是基于C语言加入了面向对象特性和消息转发机制的动态语言,这意味着它不仅需要一个编译器,还需要Runtime系统来动态创建类和对象,进行消息发送和 ...

  2. CDHtmlDialog加壳HTML5页面跳转错误解决(原)

    HTML5+Native方式开发应用程序,遇到的一个问题:HTML5实现的阅读器在打开文档时,CDHtmldialog类的跳转函数报错,忽略错误程序可以正确执行. 错误代码:OnNavigateCom ...

  3. Clustering by density peaks and distance

    这次介绍的是Alex和Alessandro于2014年发表在的Science上的一篇关于聚类的文章[13],该文章的基本思想很简单,但是其聚类效果却兼具了谱聚类(Spectral Clustering ...

  4. php技术概要汇总

    php搜索-> sphinx     coreseek : 中文分词.中文搜索     samba  :把linux服务器端目录映射的本地. 视频截图插件.音频视频转换(ffmpeg): 1)w ...

  5. DataTable 的数据导出到 Excel

    如果有个DataTable类型的数据,可以这样导出到Excel中: public static void ExportToExcel(DataTable dt, string fileName) { ...

  6. SQL Server2008附加数据库失败

    今天旁晚时分,我准备把老师在上课时候发给我们的一个数据库附加到我的SQL Server2008上面去,本来在学校机房用的SQL Server2000是很顺利地就成功了,但是把*.mdf文件附加到我的0 ...

  7. 开发一个struts2的实例

    前面一篇博客(实现struts2框架)带大家对基于mvc业务流程熟悉了一下,现在我们就用对mvc实现最好的框架struts2来开发一个应用实例.虽然现在MyEclipse8.5以上版本已经开始支持St ...

  8. insert 另外一种用法

    then into dept01(id) values(deptno) then into dept02(id) values(deptno) else into dept03(id) values( ...

  9. 一次配置jdk环境变量的感悟

    开发java也一年多了,昨日一次偶然的机会,想在dos命令下执行一个程序,发现在 命令行输入 javac Test.java的时候,竟然提示javac不是内部命令, 之后输入 java ,也提示不是内 ...

  10. js学习笔记—转载(闭包问题)

    ---恢复内容开始--- 闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现.     一.变量的作用域 要理解闭包,首先必须理解Javascrip ...