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. C++中的inline函数

    内联函数: () 内联函数定义和作用: 将一个函数声明为inline,那么函数就成为内联函数.内联函数通常就是它在程序中每个调用点上“内联地”展开.从定义上看,内联函数跟一般函数不一样,一般函数调用的 ...

  2. C# TextBox 换行 滚动到最后一行

    .要让一个Windows Form的TextBox显示多行文本就得把它的Multiline属性设置为true. 这个大家都知道,可是当你要在代码中为Text属性设置多行文本的时候可能会遇到点麻烦:) ...

  3. eclipse中,把java函数代码折叠/展开

    首先,在eclipse 中开启设置代码折叠功能 1. windows->perferences->General->Editors->Structured Text Edito ...

  4. 我和ip_conntrack不得不说的一些事

    面对让人无语的ip_conntrack,我有一种说不出的感觉!自从接触它到现在,已经两年多了,其间我受到过它的恩惠,也被它蹂躏过,被它玩过,但是又不忍心舍弃它,因为我找不到更好的替代.工作中,学习中, ...

  5. 03 InnoDB锁问题

    InnoDB与MyISAM的最大不同有两点:一是支持事务(TRANSACTION):二是采用了行级锁.行级锁与表级锁本来就有许多不同之处,另外,事务的引入也带来了一些新问题.下面我们先介绍一点背景知识 ...

  6. W3C XML Schema 教程

    转自:http://www.blogjava.net/sham2k/articles/179825.html W3C XML Schema 教程 XML SCHEMA教程 本教程是笔者学习W3C的&l ...

  7. Fliptile

      开关题   尺度法  Fliptile Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 3394   Accepted:  ...

  8. 纯JS操作服务器绑定控件(Repeat)实现表头升降排序

    JS实现功能 var obj = function (id) { return "string" == typeof id ? document.getElementById(id ...

  9. 怎么在html页面和js里判断是否是IE浏览器

    HTML里: HTML代码中,在编写网页代码时,各种浏览器的兼容性是个必须考虑的问题,有些时候无法找到适合所有浏览器的写法,就只能写根据浏览器种类区别的代码,这时就要用到判断代码了.在HTML代码中, ...

  10. LInux下socket编程学习笔记

    1.socket套接字: socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,都可以用“打开open –> 读写write/read –> 关闭close”模 ...