其中迷宫必须输入为如下形式的矩形:
0 0 0 0 0 0 0 0 0 0 0 0
0 x x x x x x x x x x x 0
0 x x x x x x x x x x x 0
0 x x x x x x x x x x x 0
0 x x x x x x x x x x x 0
0 x x x x x x x x x x x 0
0 x x x x x x x x x x x 0
0 x x x x x x x x x x x 0
0 0 0 0 0 0 0 0 0 0 0 0
其中x,要么为0,要么为1; 其中外围的0表示墙壁(亦即边界)
而原点与终点的输入则为上述矩阵的下标号(0,0)开始,如第一行第一列的点为起点则输入为1 1,终点同理。
求解思路主要运用的是回溯法,即,当下一步不可通时,回到上一步继续探测,直至找到终点或者所有路径都探测完为止。
代码如下:
#include <iostream>
using namespace std;
#define MAX_SIZE 100
struct MazeNode{
bool passable; //0表示不能通过,1表示可以通过
int passed; //0表示为经过该点,1表示该点可以通过,-1表示该点不可通
int xPosition; //x坐标
int yPosition; //y坐标
};
struct Stack{
MazeNode* elem;
int top;
};
void InitStack(Stack& stack){
stack.elem = new MazeNode[MAX_SIZE*10];
stack.top = 0;
}
bool IsEmpty(const Stack& stack){
if(stack.top == 0)
return true;
else return false;
}
void Push(Stack& stack, MazeNode elem){
stack.elem[stack.top] = elem;
stack.top++;
}
MazeNode Pop(Stack& stack){
if(!IsEmpty(stack)){
stack.top--;
MazeNode elem = stack.elem[stack.top];
return elem;
}else{
cout<<"栈已空!"<<endl;
}
}
bool FindPath(MazeNode* maze[], MazeNode start, MazeNode end){
Stack stack;
InitStack(stack);
if(start.passable == 0){
cout<<"入口不可通!"<<endl;
return false;
}
start.passed = 1;
MazeNode current = start;
Push(stack,current);
do{
if(current.passable == end.passable && current.xPosition == end.xPosition && current.yPosition == end.yPosition){
return true;
}
int x = current.xPosition;
int y = current.yPosition;
if(maze[x][y+1].passed == 0 && maze[x][y+1].passable == 1){//如果右邻点没走过且可通
cout<<"向右走到"<<"("<<x<<","<<y+1<<")->";
maze[x][y+1].passed = 1;
current = maze[x][y+1];
Push(stack,current);
}else if(maze[x+1][y].passed == 0 && maze[x+1][y].passable == 1){//如果下邻点没走过且可通
cout<<"向下走到"<<"("<<x+1<<","<<y<<")->";
maze[x+1][y].passed = 1;
current = maze[x+1][y];
Push(stack,current);
}else if(maze[x][y-1].passed == 0 && maze[x][y-1].passable == 1){//如果左邻点没走过且可通
cout<<"向左走到"<<"("<<x<<","<<y-1<<")->";
maze[x][y-1].passed = 1;
current = maze[x][y-1];
Push(stack,current);
}else if(maze[x-1][y].passed == 0 && maze[x-1][y].passable == 1){//如果上邻点没走过且可通
cout<<"向上走到"<<"("<<x-1<<","<<y<<")->";
maze[x-1][y].passed = 1;
current = maze[x-1][y];
Push(stack,current);
}else if(!IsEmpty(stack)){//如果栈不空,则回朔
current = Pop(stack);
cout<<"回退到"<<"("<<current.xPosition<<","<<current.yPosition<<")->";
}else{//如果栈为空,则无解
return false;
}
}while(true);
}
void main(){
MazeNode** maze = NULL;
Stack stack;
InitStack(stack);
int i, j, row, col;
cout<<"迷宫大小(行、列数):";
cin>>row>>col;
if(row < 1 || col < 1){
cout<<"输入非法!"<<endl;
cout<<"程序结束!"<<endl;
return ;
}
maze = new MazeNode*[row];
if(!maze){
cout<<"分配内存失败!程序结束!"<<endl;
return ;
}
for(i = 0; i < row; i++){
maze[i] = new MazeNode[col];
if(!maze[i]){
cout<<"分配内存失败!程序结束!"<<endl;
return ;
}
}
cout<<"请输入迷宫:"<<endl;
for(i = 0; i < row; i++){
for(j = 0; j < col; j++){
cin>>maze[i][j].passable;
maze[i][j].xPosition = i;
maze[i][j].yPosition = j;
maze[i][j].passed = 0;
Push(stack,maze[i][j]);
}
}
cout<<"请输入起始点与终止点:"<<endl;
MazeNode start, end;
cin>>start.xPosition>>start.yPosition>>end.xPosition>>end.yPosition;
start = maze[start.xPosition][start.yPosition];
end = maze[end.xPosition][end.yPosition];
if(FindPath(maze,start,end)){
cout<<endl<<"走出迷宫!"<<endl;
}else {
cout<<endl<<"迷宫不可通!"<<endl;
}
cout<<endl;
}