今天做实验,走迷宫问题,要求用递归与非递归两种方法:
要求:
1)数据结构:
² 用二维数组MAZE[m+2][n+2]表示迷宫的结构,数组中的值为1表示是墙,为0表示可以走通。(用MAZE[m+2][n+2]而不用MAZE[m][n]的原因在于想表示和编写代码的时候简单些,而且让迷宫周围都是墙,防止错误的走出去)
² 用二维数组MARK[m+2][n+2]表示迷宫是否被走过,主要是为了回溯时已经证明走不通的路线就不要再去走了。(用MARK[m+2][n+2]而不用MARK[m][n]的原因在于想表示和编写代码的时候简单些)
² 二维数据MOVE[8][2]是为了更方便的移动到下一步,改变坐标。这个二维数组是为了更好的转换坐标(八个方向,从0到7),而且也能避免重复走路
² 用栈保存走过的路径
(2)输出:
² 迷宫布局,用0表示可以走通的地方,用1表示墙
² 如果能走通,则输出路径和路径的长度;若不能走通,则输出提示不能走通
² 带有路径的迷宫布局
以下是代码:
maze.h
1 #include<stack> 2 using namespace std; 3 const int rowsize = 10; //定义走通路径时数组的下标 4 const int colsize = 11; 5 const int MOVE[8][2]={{0,1},{1,1},{1,0},{1,-1},{-1,0},{-1,-1},{0,-1},{-1,1}}; //定义路径 6 struct step //存放走通的路 7 { 8 int x; 9 int y; 10 int mov; 11 }; 12 class Maze 13 { 14 public: 15 Maze(); 16 int getmaze(int i,int j); //返回路径 17 bool solve(int i, int j); //递归算法 18 bool path(); //非递归算法 19 int maze[12][12]; //用于储存迷宫 20 stack<step> STACK; //用于储存步骤 21 };
maze.cpp
1 #include"maze.h" 2 #include<ctime> 3 #include<cstdlib> 4 #include<iostream> 5 using namespace std; 6 Maze::Maze() 7 { 8 srand((unsigned int) time(NULL)); //随机生成一个迷宫 9 for(int i=0;i<12;i++) 10 { 11 for(int j=0;j<12;j++) 12 { 13 if(i!=0&&i!=11&&j!=0&&j!=11) 14 { 15 maze[i][j]=(int)rand()%2; 16 } 17 else 18 maze[i][j]=1; 19 } 20 } 21 maze[1][1]=0; //将初位置和末位置都设为可以走通的状态'0' 22 maze[10][10]=0; 23 maze[10][11]=0; 24 } 25 int Maze::getmaze(int i,int j) 26 /*获取迷宫*/ 27 { 28 return maze[i][j]; 29 } 30 bool Maze::path() //非递归算法 31 { 32 maze[1][1]='x'; //将第一个位置压栈 33 int g=0,h=0; 34 step STEP; 35 STEP.x=1; 36 STEP.y=1; 37 STEP.mov=0; 38 STACK.push(STEP); 39 while(!STACK.empty()) //寻找路径 40 { 41 STEP=STACK.top(); 42 STACK.pop(); 43 while(STEP.mov!=8 ) //按八个方向寻找路径 44 { 45 g=STEP.x+MOVE[STEP.mov][0]; 46 h=STEP.y+MOVE[STEP.mov][1]; 47 if( g==rowsize && h==colsize) 48 { 49 return true; //迷宫可以走通 50 } 51 if (maze[g][h]==0) 52 { 53 maze[g][h]='x'; 54 STACK.push(STEP); 55 STEP.x=g; 56 STEP.y=h; 57 STEP.mov=0; 58 } 59 else 60 { 61 STEP.mov=STEP.mov+1; //改变方向搜索 62 } 63 } 64 if(STEP.mov==8) //若八个方向都走不通就把该位置标记为'Y'即表示该位置已经走过且走不通 65 { 66 maze[STEP.x][STEP.y]='Y'; 67 STEP.mov=0; 68 } 69 } 70 return false; //走不通 71 } 72 73 bool Maze::solve(int i,int j) 74 { 75 bool finish = false; 76 maze[i][j] = 'X'; 77 if (i == rowsize && j == colsize) 78 return true; // because we're done 79 if (!finish && maze[i+1][j] == 0) 80 finish = solve(i+1, j); 81 if (!finish && maze[i][j+1] == 0) 82 finish = solve(i, j+1); 83 if (!finish && maze[i-1][j] == 0) 84 finish = solve(i-1, j); 85 if (!finish && maze[i][j-1] == 0) 86 finish = solve(i, j-1); 87 if (!finish && maze[i-1][j-1] == 0) 88 finish = solve(i-1, j-1); 89 if (!finish && maze[i-1][j+1] == 0) 90 finish = solve(i-1, j+1); 91 if (!finish && maze[i+1][j+1] == 0) 92 finish = solve(i+1, j+1); 93 if (!finish && maze[i+1][j-1] == 0) 94 finish = solve(i+1, j-1); 95 if (!finish) //无法走通,那么修改原来设置的X符号,但是不设置为0,因为这个点现在已经走过 96 maze[i][j] = 'Y'; 97 return finish; 98 }
main.cpp
1 #include<iostream> 2 #include"maze.h" 3 using namespace std; 4 int main() 5 { 6 int i=0,j=0; 7 Maze a; //生成一个迷宫 8 cout<<"非递归算法"<<endl; 9 for(i=0;i<12;i++) //显示一个迷宫 10 { 11 for(j=0;j<12;j++) 12 { 13 cout<<a.getmaze(i,j)<<" "; 14 } 15 cout<<endl; 16 } 17 18 19 //非递归 20 bool b; //用于判断迷宫是否可以走通 21 b=a.path(); 22 cout<<"----------------------------------------------------------------"<<endl; 23 if(b==false) 24 cout<<"不能走出迷宫"<<endl; 25 else 26 { 27 cout<<"走出迷宫的路线为:"<<endl; 28 cout<<"----------------------------------------------------------------"<<endl; 29 for(i=0;i<12;i++) //显示走出迷宫的路径 30 { 31 for(j=0;j<12;j++) 32 { 33 if(a.getmaze(i,j)==0||a.getmaze(i,j)==1) 34 cout<<a.getmaze(i,j)<<" "; 35 else if(a.getmaze(i,j)=='Y') 36 cout<<'0'<<" "; 37 else 38 cout<<(char)a.getmaze(i,j)<<" "; 39 } 40 cout<<endl; 41 } 42 } 43 44 //显示走出迷宫的路径 45 for(i=0;i<12;i++) 46 { 47 for(j=0;j<12;j++) 48 { 49 if((char)a.getmaze(i,j)=='x') 50 { 51 52 cout<<"x="<<i<<"y="<<j<<" "; 53 } 54 } 55 cout<<endl; 56 } 57 58 59 60 //递归 61 bool c; 62 c=a.solve(1,1); 63 cout<<c<<endl; 64 if(c==false) 65 { 66 cout<<"不能走出迷宫!"<<endl; 67 } 68 else 69 { 70 for(i=0;i<12;i++) 71 { 72 for(j=0;j<12;j++) 73 { 74 if(a.getmaze(i,j)==0||a.getmaze(i,j)==1) 75 cout<<a.getmaze(i,j)<<" "; 76 else if(a.getmaze(i,j)=='Y') 77 cout<<'0'<<" "; 78 else 79 cout<<(char)a.getmaze(i,j)<<" "; 80 } 81 cout<<endl; 82 } 83 } 84 85 86 for(i=0;i<12;i++) 87 { 88 for(j=0;j<12;j++) 89 { 90 if((char)a.getmaze(i,j)=='X') 91 { 92 93 cout<<"x="<<i<<"y="<<j<<" "; 94 } 95 } 96 cout<<endl; 97 } 98 return 0; 99 }
一直都不怎么注意做笔记,弄得现在感觉好多东西就算做过了一会就忘了。