您的位置:首页 > 理论基础 > 数据结构算法

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

2011-10-05 21:34 896 查看
此问题中,迷宫用一个二位数组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;

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐