大一上学期的程序设计算法作业,没有利用深度搜索求出所有路径,有点遗憾。 发博客也只是记录一些大学生活的实验而已。
问题描述:以一个 m*n 的长方阵表示迷宫,0 和 1 分别表示迷宫中的通路和障碍。设计一个程序,对任意设 定的迷宫,求出一条从入口到出口的通路,或得出没有通路的结论。
这里为了调试方便,采用的是内置的7*7大小的bool型二维数组表示迷宫。
数据结构:
坐标:
struct coordinate {//坐标 int x; int y; };
迷宫属性:
struct cell {//迷宫元素 bool edge;//是否为障碍 bool visited;//是否已经访问 int direction;//方向,-1下 -2 右 1上 2左 };
存储属性的栈:
stack<cell>cellstack;
迷宫操作:
迷宫初始化:
void InitMap(cell map[7][7],bool init[7][7]) { for (int i = 0; i < 7; i++) for (int j = 0; j < 7; j++) { map[i][j].edge = init[i][j];//初始化操作 map[i][j].visited = false; } }
打印迷宫:
void printMap(cell map[7][7]) { cout << "迷宫形式为:" << endl; for (int i = 0; i < 7; i++) { for (int j = 0; j < 7; j++) { if (map[i][j].edge == 1) cout << "■"; else cout << "□"; } cout << endl; } }
迷宫内的某点是否能走:
bool feasible(cell atom) { //判定该点能走 if (atom.edge) return false; if (atom.visited) return false; return true; }
walk函数:
bool walk(cell map[7][7], int x0,int y0,int x1,int y1) { //给定地图与起点、终点 map[x0][y0].visited = 1;//起点访问 map[x0][y0].direction = 0;//起点访问 cellstack.push(map[x0][y0]);//起点入栈 cout << "起点:(" << x0 << "," << y0 <<")"<< endl; cout << "终点:(" << x1 << "," << y1 << ")" << endl; int x = x0; int y = y0; while (!cellstack.empty()) { //如果栈不空 if (x + 1<7&&map[x + 1][y].edge == 0&& map[x + 1][y].visited==0) { //尝试向下走,不是障碍且未被访问 x++; map[x][y].direction = 1;//标记上 map[x][y].visited = 1;//该点被访问 cellstack.push(map[x][y]); if (x == x1 && y == y1)//找到通路,返回1 return 1; } else if (y + 1 < 7 && map[x][y + 1].edge == 0 && map[x][y + 1].visited == 0) { //尝试向右走,不是障碍且未被访问 y++; map[x][y].direction = 2;//标记左 map[x][y].visited = 1;//该点被访问 cellstack.push(map[x][y]); if (x == x1 && y == y1) return 1; } else if (x - 1 >=0 && map[x-1][y].edge == 0 && map[x-1][y].visited == 0) { //尝试向上走,不是障碍且未被访问 x--; map[x][y].direction = -1;//标记下 map[x][y].visited = 1;//该点被访问 cellstack.push(map[x][y]); if (x == x1 && y == y1) return 1; } else if (y-1>=0 && map[x][y - 1].edge == 0 && map[x][y - 1].visited == 0) { //尝试向左走,不是障碍且未被访问 y-- ; map[x][y].direction = -2;//标记右 map[x][y].visited = 1;//该点被访问 cellstack.push(map[x][y]); if (x == x1 && y == y1) return 1; } else { //都不能走 if (!cellstack.empty()) { if (cellstack.top().direction == -1) x++; if (cellstack.top().direction == -2) y++; if (cellstack.top().direction == 1) x--; if (cellstack.top().direction == 2) y--; } cellstack.pop();//出栈,坐标变换 } } //找不到通路,返回0 return 0; }
打印通路:
void display(int x1, int y1) { //打印通路 //cout << cellstack.size() << endl; int num = cellstack.size(); coordinate *p = new coordinate[num];//创建适合大小的数组 p[0].x = x1, p[0].y = y1; int x = x1, y = y1; //初始化终点 for (int i = 1; i < num; i++) { if (cellstack.top().direction == -1) { p[i].x = ++x; p[i].y = y; } if (cellstack.top().direction == -2) { p[i].x = x; p[i].y = ++y; } if (cellstack.top().direction == 1) { p[i].x = --x; p[i].y = y; } if (cellstack.top().direction == 2) { p[i].x = x; p[i].y = --y; } cellstack.pop(); } for (int i = num - 1; i >= 0;i--) { cout <<"->"<< "(" << p[i].x << "," << p[i].y << ")"; } cout << endl; }
主函数:
int main()
{
bool mapinit[7][7] = {
0,1,0,1,1,0,0,
0,0,0,0,1,0,1,
1,1,1,0,0,0,1,
0,0,1,1,1,0,0,
1,1,0,0,1,0,0,
0,1,1,0,0,1,0,
0,0,0,0,1,0,0
};
cell map[7][7];
InitMap(map, mapinit);
printMap(map);
//if (walk(map, 0, 0, 6, 5)) {
// cout << "找到了一条通路:" << endl;
// display(6, 5);
//}
if (walk(map, 0, 0, 3, 0)) {
cout << "\n结果:\n找到了一条通路:" << endl;
display(3, 0);
}
else
cout << "\n结果:\n无通路" << endl;
return 0;
}
成功示例:
失败示例:
结语:很早写的,当然现在的代码水平更是菜,哈哈哈,写博客记录一下而已。需要改进的地方很多,没有支持自动输入迷宫,没有利用深搜遍历所有的路径。利用面对对象的方法将迷宫看作一个对象,编写迷宫类,将迷宫的动作作为方法,坐标作为成员变量可能会比较好。