数据结构和算法设计(迷宫求解问题的栈和队列的实现)

此问题中,迷宫用一个二位数组data[ ][ ]表示,data[i][j]的值为0,则表示该点为通路;如果为1,则表示该点为障碍;如果为-1,则表示该点已经走过。数组的四周值都为1,表示边界。给定起点和终点,求起点到终点的路径。

可以使用栈对二维数组进行深度优先搜索,直到找到终点的时候停止搜索。此方案找到的路径不一定是最短路径。如果要好到最短路径,可以使用队列来进行二维数组的宽度优秀搜索,直到找到终点停止搜索,然后从队列中找出我们需要的最短路径。废话少说,代码如下:

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

public class Maze {
private int[][] data = null;//数据1:障碍,0:出路,-1:此点已经通过
private Stack<Point> stack = new Stack<Point>() ;
private List<Point> queue = new ArrayList<Point>() ;//用数组模拟队列操作

public Maze(int[][] data){   //出使化
this.data = data ;
}

public boolean getPath(Point start , Point end){
boolean isFind = false ;//是否找到
Point temp = null;

stack.push(start) ;//将起点入栈
this.data[start.getX()][start.getY()] = -1 ;//起点标记为走过
while(!stack.isEmpty()){//栈不为空时进入循环

temp = stack.lastElement() ;//得到栈顶元素
int x = temp.getX() ;
int y = temp.getY() ;
int di = temp.getDirection() ;//得到方向

if(temp.equals(end)){//找到终点
printPath() ;
return true ;
}

isFind = false ;
while(di<4 && !isFind){//当方向没有找完,而且没有找到
di++ ;//下一个方向寻找
switch(di){
case 0: x = temp.getX() – 1 ; y = temp.getY() ; break ;//向上
case 1: x = temp.getX() ; y = temp.getY() + 1 ; break ;//向右
case 2: x = temp.getX() + 1 ; y = temp.getY() ; break ;//向下
case 3: x = temp.getX() ; y = temp.getY() – 1 ; break ;//向左
default : break ;
}
if(this.data[x][y] == 0){//如果找到则跳出循环
isFind = true ;
}
}

if(isFind){//如果找到了出路,则将此节点入栈
stack.lastElement().setDirection(di) ;//设置上一个节点的方向
Point p = new Point(x , y , -1) ;//新节点入栈
stack.push(p) ;
this.data[x][y] = -1 ;//将当前节点标记为障碍
}else{//如果没有找到节点 
Point p = stack.pop() ;//出栈
this.data[p.getX()][p.getY()] = 0 ;//当前节点标记为通路
}
}
return false ;
}

public boolean getPath2(Point start, Point end){//使用队列找到起点到终点的最短路径
int index = -1 ;//队列中下标值 
Point temp = null ;
boolean isFind = false ;
int x=-1 , y=-1 , di=-1 ;

queue.add(start) ;//起点入队列
this.data[start.getX()][start.getY()] = – 1 ; //起点标记为走过
while(!queue.isEmpty() && !isFind){
index++ ;
temp = queue.get(index) ;//得到队列中寻找的节点
if(temp.equals(end)){
printPath2(index) ;//index为终点在队列中的下标值
return true ;
}

isFind = false ;
for(di = 0 ; di<4 ; di++){
switch(di){
case 0: x = temp.getX() – 1 ; y = temp.getY() ; break ;//向上
case 1: x = temp.getX() ; y = temp.getY() + 1 ; break ;//向右
case 2: x = temp.getX() + 1 ; y = temp.getY() ; break ;//向下
case 3: x = temp.getX() ; y = temp.getY() – 1 ; break ;//向左
default : break ;
}

if(this.data[x][y] == 0){//节点是通路
queue.add(new Point(x , y , index)) ;
this.data[x][y] = -1 ;//将此点标记为走过
}
}
}
return false ;
}

public void printPath(){
for(int i=0 ; i<stack.size() ; i++){
Point p = stack.get(i) ;
System.out.println(“[” + p.getX() + “,” + p.getY() + “]”);
}
}

public void printPath2(int x){
int index = x ;//终点在队列中的下标
while(index != -1){
int pre = queue.get(index).getDirection() ;//得到前一个点的下标
queue.get(index).setDirection(-1) ;//将我们需要的路径上的点的前驱置为-1
index = pre ;
}

for(int i=0,len=queue.size() ; i<len ; i++){
Point p = queue.get(i) ;
if(p.getDirection() == -1){
System.out.println(“[” + p.getX() + “,” + p.getY() + “]”);
}
}
}

public static void main(String[] args) {
int mg[][] =       //定义迷宫,0代表通路,1代表障碍
{ {1,1,1,1,1,1,1,1,1,1},
{1,0,0,1,0,0,0,1,0,1},
{1,0,0,1,0,0,0,1,0,1},
{1,0,0,0,0,1,1,0,0,1},
{1,0,1,1,1,0,0,0,0,1},
{1,0,0,0,1,0,0,0,0,1},
{1,0,1,0,0,0,1,0,0,1},
{1,0,1,1,1,0,1,1,0,1},
{1,1,0,0,0,0,0,0,0,1},
{1,1,1,1,1,1,1,1,1,1} };
Maze m = new Maze(mg) ;
Point p1 = new Point(1 , 1 ) ;
Point p2 = new Point(8 , 8 ) ;
// m.getPath(p1 , p2) ;
m.getPath2(p1 , p2) ;
}
}

在此类中用到了一个辅助类Point,代码如下:

package edu.qc.stack;

public class Point {
private int x;
private int y;
private int direction;//如果使用栈,此变量代表从此点经过时候的方向,0:上,1:右,2:下,3:左;如果使用队列,则此变量代表路径中此点的前一个节点在队列中的下标值

public Point(){
this.x = 0 ; 
this.y = 0 ;
this.direction = -1 ;
}

public Point(int x , int y){
this.x = x ;
this.y = y ;
this.direction = -1 ;
}

public Point(int x , int y , int direction){
this.x = x ;
this.y = y ;
this.direction = direction ;
}

public int getX() {
return x;
}

public void setX(int x) {
this.x = x;
}

public int getY() {
return y;
}

public void setY(int y) {
this.y = y;
}

public int getDirection() {
return direction;
}

public void setDirection(int direction) {
this.direction = direction;
}

@Override
public boolean equals(Object obj) {
if(obj instanceof Point){
Point p = (Point)obj ;
if((p.getX() == this.x) && (p.getY() == this.y)){
return true ;
}else{
return false ;
}
}
return false ;
}

@Override
public int hashCode() {
return super.hashCode() + x + y;
}
}

    原文作者:舞伴问题
    原文地址: https://blog.csdn.net/xxqi1229/article/details/6845821
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞