最近用C学了数据结构的迷宫求解问题,但是个人感觉用C实现特别麻烦。索性用Java来实现了。总体的思路不太复杂:首先创建一个栈结构,可以方便的输出最短的路径,然后就是合理的运用递归的思想来进行路径的回溯。先上代码。
interface Method{//实现迷宫的栈结构的接口
int MAX = 50;//栈的最大存储量,也就是路径的最长量
void StackInit(StackList stackList);//初始化
void StackAdd(StackList stackList, place Number);//插入
void StackDelete(StackList stackList);//删除
void Display(StackList stackList);//打印(测试用)
}
class StackList{//栈结构
place[] data;
int size;
int capacity;
}
class My_Method implements Method{//实现栈相关方法的类
@Override
public void StackInit(StackList stackList) {
if(stackList == null){
return;
}
stackList.data = new place[MAX];
stackList.capacity = MAX;
stackList.size = 0;
}
@Override
public void StackAdd(StackList stackList, place Number) {
if(stackList == null){
return;
}
if(stackList.size == stackList.capacity){
return;
}
stackList.data[stackList.size] = Number;
stackList.size++;
}
@Override
public void StackDelete(StackList stackList) {
if(stackList == null){
return;
}
if(stackList.size == 0){
return;
}
stackList.size--;
}
@Override
public void Display(StackList stackList) {
if(stackList == null){
return;
}
for(int i = 0;i<stackList.size;i++){
System.out.print(" "+stackList.data[i]);
}
}
}
//-----------------------------------------------------------
interface Maze_Method{//有关迷宫地图的实现方法的接口
int ROW = 6;//迷宫的行与列
int COL = 6;
boolean Exit(Maze maze,place now_place,place start);//检查是不是出口
void mark(Maze maze, place now_place, place prev_place);//做标记
boolean CanStay(Maze maze, place now_place, place prev_place);//判断是否可以落到这个位置上
void Walk(Maze maze, place start, place now_place, place prev_place, StackList cur, StackList _short, Method My_Test);//递归函数
void Init(Maze maze);//初始化地图
void Display(Maze maze);//打印地图
}
interface Maze_area{
int ROW = 6;//迷宫的大小
int COL = 6;
}
class Maze implements Maze_area{//迷宫地图
int[][] map = new int[ROW][COL];
}
class My_Maze_Method implements Maze_Method{//实现迷宫相关的方法
@Override
public void Init(Maze maze) {//初始化地图
int[][] New_Map = new int[][]{{0,1,0,0,0,0},
{1,1,0,0,0,0},
{0,1,0,1,1,1},
{1,1,1,1,0,0},
{0,0,0,1,0,0},
{0,0,0,1,0,0,}};
maze.map = New_Map;
}
@Override
public void Display(Maze maze) {//打印地图
for(int i = 0;i<maze.map.length;i++){
for(int j = 0;j<maze.map[0].length;j++){
System.out.print(" "+ maze.map[i][j]);
}
System.out.println();
}
}
@Override
public boolean Exit(Maze maze, place now_place, place start) {//检查是否是出口
if(now_place == start){
return false;
}
if(now_place.row == 0 || now_place.row == ROW-1 || now_place.col == 0 || now_place.col == COL-1){
return true;
}
return false;
}
@Override
public boolean CanStay(Maze maze, place now_place, place prev_place) {//检查某位置是否合法
if((now_place.row >= ROW) || (now_place.row < 0) || (now_place.col >= COL) || (now_place.col < 0)){
return false;
}
if(maze.map[now_place.row][now_place.col] == 0){
return false;
}
if(maze.map[now_place.row][now_place.col] == 1){
return true;
}
if(maze.map[prev_place.row][prev_place.col] > (maze.map[now_place.row][now_place.col] + 1)){
return true;
}
return false;
}
@Override
public void mark(Maze maze, place now_place, place prev_place) {//标记一个位置
if (prev_place.row == -1 && prev_place.col == -1) {
maze.map[now_place.row][now_place.col] = 2;
} else {
maze.map[now_place.row][now_place.col] = maze.map[prev_place.row][prev_place.col] + 1;
}
}
@Override
public void Walk(Maze maze, place start, place now_place, place prev_place, StackList cur, StackList _short, Method My_test) {//递归函数
if(!CanStay(maze,now_place,prev_place)){//看是否可以在这个位置走
return;
}
mark(maze,now_place,prev_place);//做标记
My_test.StackAdd(cur,now_place);//将能走的地方入栈
if(Exit(maze,now_place,start)){//如果是出口,那么把cur栈和_short栈的大小做比较,
if(_short.size == 0) {//把比较小的那个保存在_short栈中
_short.data = cur.data;
_short.size = cur.size;
_short.capacity = cur.capacity;
}
if(_short.size > cur.size){
_short.data = cur.data;
_short.size = cur.size;
_short.capacity = cur.capacity;
}
My_test.StackDelete(cur);//如果是出口,那么删除栈顶,回溯
System.out.println("找到一个出口");
return;
}
//顺时针扫描一个位置的上下左右
place up = new place(now_place.row-1,now_place.col);
prev_place = now_place;
Walk(maze,start,up,prev_place,cur,_short,My_test);
place right = new place(now_place.row,now_place.col+1);
prev_place = now_place;
Walk(maze,start,right,prev_place,cur,_short,My_test);
place down = new place(now_place.row+1,now_place.col);
prev_place = now_place;
Walk(maze,start,down,prev_place,cur,_short,My_test);
place left = new place(now_place.row,now_place.col-1);
prev_place = now_place;
Walk(maze,start,left,prev_place,cur,_short,My_test);
My_test.StackDelete(cur);
}
}
//-------------------------------------------------------
class place{//描述点的位置
int row;
int col;
place(int row, int col){
this.row = row;
this.col = col;
}
place(){}
}
public class Main{
public static void main(String[] args){
Maze My_Maze = new Maze();//创建栈对象
Method Test_stack = new My_Method();//创建栈的实现对象
StackList stackList_cur = new StackList();//创建每条路径的栈对象
StackList stackList_short = new StackList();//创建代表最短路径的栈对象
Test_stack.StackInit(stackList_cur);//初始化栈对象
Test_stack.StackInit(stackList_short);//初始化栈对象
Maze_Method New_Test = new My_Maze_Method();//初始化迷宫的实现对象
place Enter = new place(0,1);//创建入口对象
place Prev = new place(-1,-1);//创建前一个对象(这里的赋值主要针对入口点,我们可以直接把它赋值成特定的非法值)
Maze maze = new Maze();//创建地图对象
New_Test.Init(maze);//初始化地图
New_Test.Walk(maze,Enter,Enter,Prev,stackList_cur,stackList_short,Test_stack);//实现迷宫求解的主要递归方法
New_Test.Display(maze);//打印迷宫路径
System.out.println("迷宫的最短路径是:");
for(int i = 0; i<stackList_short.size;i++){//打印最短路径
System.out.println("("+stackList_short.data[i].row+","+stackList_short.data[i].col+")");
}
}
}
嗯,如果有不合理的地方还请大神指教。