图的搜索之广度优先

广度优先

每次搜索·,搜索所有可达的点

思路分析

  1. 从起点出发查找所有可达的点。并加入队列
  2. 出队元素查找所有可达的点。并加入队列
  3. 继续第二步操作

代码再现

public class Bfs {

	//地图的大小
	int n,m;
	//定义地图,如果值为0表示节点无障碍,值为1表示节点有障碍
	int[][] data = null; 
	//标记已经走过的节点
	boolean[][] marked = null;
	//开启调试
	boolean debug = true;
	/**
	 * 0,1  表示往前走
	 * 0,-1  表示往后走
	 * 1,0  表示往上走
	 * -1,0  表示往下走
	 */
	int[][] direction = {{0,1},{0,-1},{1,0},{-1,0}};
	//最短距离
	int minDepth = Integer.MAX_VALUE;
	
	//目标位置
	point dest;
	
	/**
5 4
0 0 1 0
0 0 0 0
0 1 0 1
0 0 0 0
0 0 0 1
3 2	
	 * @param x 初始位置x
	 * @param y 初始位置y
	 */
	public void bfsSearch(int x,int y) {
		
		//初始化一个队列
		LinkedBlockingQueue<Point> queue = new LinkedBlockingQueue();
		//降低一个元素加入
		queue.add(new Point(x, y));
		
		while( !queue.isEmpty() ) {
			//取出一个元素
			Point p = queue.poll();
			if(p.dx==dest.dx && p.dy ==dest.dy) {
				System.out.println("找到了..."+p);
				break;
			}
			//从四个方向将所有的元素都加入队列
			for(int i=0; i<direction.length; i++){
				int nextx = direction[i][0]+p.dx;
				int nexty = direction[i][1]+p.dy;
				
				//超出边界,位置无效,退出
				if(nextx<0 || nextx>=m || nexty<0 || nexty>=n)  
					continue;
				
				//该位置存在障碍物不能走的,需要绕路
				if( data[nextx][nexty]==1 ) 
					continue;
				
				//当前位置已经走过,不要再走了
				if( marked[nextx][nexty]==true ) 
					continue;
				//标记当前元素
				marked[nextx][nexty]=true;
				//将元素加入队列
				queue.add(new Point(nextx, nexty));
			}
		}
	}
	
	public static void main(String[] args) {
		Bfs bfs = new Bfs();
		//关闭调试
		bfs.debug =false;
		try(Scanner dis = new Scanner(System.in)){
			bfs.m = dis.nextInt();
			bfs.n = dis.nextInt();
			bfs.data = new int[bfs.m][bfs.n];
			bfs.marked =  new boolean[bfs.m][bfs.n];
			for(int i=0; i<bfs.m ;  i++ ) {
				for(int j=0; j<bfs.n; j++) {
					bfs.data[i][j] = dis.nextInt();
				}
			}
			bfs.dest = new point(dis.nextInt(),dis.nextInt());
		}
		bfs.bfsSearch(0, 0);
	}
	
	static class Point {
		int dx;
		int dy;
		
		public Point(int dx,int dy) {
			this.dx = dx;
			this.dy = dy;
		}
		
		@Override
		public String toString() {
			return "Point [dx=" + dx + ", dy=" + dy + "]";
		}
		
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值