今天呢,让我们来用栈求解一下数据结构中的著名问题---迷宫问题
Maze.txt
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 0 1 0 0 0 0 1 1 1 1 0 1 0 1 1 0 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 0 1 1 1 1 0 1 1 1 1 0 1 1 1 1 0 1 1 1 1 0 1 1 1 1 0 1 1
其中呢,0代表可以走的路,而1呢,则代表的是不可以走的路(墙)
首先呢,我们先来定义一个结构体,用来存储坐标
struct Pos { size_t _row;//行 size_t _col;//列 };
接下来呢,我们需要从Maze.txt读入迷宫
void GetMaze(int *maze,size_t N) { FILE *fp = fopen("1.txt","r"); if (fp == NULL) { throw invalid_argument("Read maze filed"); } for (size_t i = 0; i < N; ++i) { for (size_t j = 0; j < N;) { char ch = fgetc(fp); if (ch == '0' || ch == '1') { maze[i*N + j] = ch - '0'; ++j; } else if (ch == EOF) { throw invalid_argument("Maze Error"); } } } }
就是判断这个位置是不是0
bool CheckIsAccess(int *maze,size_t N,Pos next) { if (maze[next._row*N + next._col] == 0) { return true; } return false; }
利用非递归的方式求解
bool GetMazePath(int *maze,size_t n,Pos entry,stack<Pos>&path) { maze[entry._row*N + entry._col] = 2; Pos cur,next; cur = entry; path.push(entry); while (!path.empty()) { cur = path.top(); if (cur._row == N - 1) { return true; } next = cur; next._row += 1; if (CheckIsAccess((int*)maze,N,next) == true) { path.push(next); maze[next._row*N + next._col] = 2; continue; } next = cur; next._row -= 1; if (CheckIsAccess((int*)maze,next) == true) { path.push(next); maze[next._row*N + next._col] = 2; continue; } next = cur; next._col += 1; if (CheckIsAccess((int*)maze,next) == true) { path.push(next); maze[next._row*N + next._col] = 2; continue; } next = cur; next._col -= 1; if (CheckIsAccess((int*)maze,next) == true) { path.push(next); maze[next._row*N + next._col] = 2; continue; } next = cur; path.pop(); } return false; }
利用递归的方式求解
void GetMazePath_R(int *maze,stack<Pos>&path) { if (entry._row == N - 1) { return; } Pos cur,next; cur = entry; next = cur; next._row += 1; if (CheckIsAccess((int*)maze,next) == true) { path.push(next); maze[next._row*N + next._col] = 2; GetMazePath_R(maze,next,path); } next = cur; next._row -= 1; if (CheckIsAccess((int*)maze,next) == true) { path.push(next); maze[next._row*N + next._col] = 2; GetMazePath_R(maze,path); } next = cur; next._col += 1; if (CheckIsAccess((int*)maze,path); } next = cur; next._col -= 1; if (CheckIsAccess((int*)maze,path); } next = cur; }
对非递归的方法求最短路径
ReMaze表示的是重置迷宫
void ReMaze(int* maze,size_t N) { for (size_t i = 0; i < N; ++i) { for (size_t j = 0; j < N; ++j) { if (maze[i*N + j] != 1) { maze[i*N + j] = 0; } } } } void TestMaze() { try { int maze[N][N] = { 0 }; int curmaze[N][N] = { 0 }; GetMaze((int*)maze,N); stack<Pos> path,MinPath,empty; while (GetMazePath((int*)maze,{ 2,0 },path)) { if (path.size() < MinPath.size()||MinPath.size() == 0) { MinPath = path; } ReMaze((int*)maze,N); maze[path.top()._row][path.top()._col] = 1;//将上次的出口改为1 path = empty; } cout << "Min path:" << MinPath.size() << endl; } catch (exception &e) { cout << e.what() << endl; } }