按照左、右、上、下方向,每走一步,就把将要走的节点赋值为此节点值+1,走过的路径也可以重复行走。条件是本节点值+1必须小于已走过的节点的值(墙不能走),这样遍历所有的节点,便可以记录最短的路径。
C++代码实现如下:
#include <iostream> #include <iomanip> #include <stack> using namespace std; class Maze { public: //成员变量初始化 Maze(size_t start_x, size_t start_y, size_t end_x, size_t end_y) :m_start(Node(start_x, start_y)), m_end(Node(end_x, end_y)) { m_maze[start_x][start_y] = 1; //迷宫入口初始化为1,避免重复走 } //查找最短路径 void searchPath() { searchPath(m_tempPath, m_start, m_end);//调用私有函数 } //打印最短路径走过的点 void printPath() { while(!m_path.empty()) { cout << '(' << m_path.top().m_x << ',' << m_path.top().m_y << ')'<< "——>" <<m_maze[m_path.top().m_x][m_path.top().m_y] << endl; m_path.pop(); } } //打印遍历后的数组节点值 void printMaze()const { for(size_t i = 0; i < 10; ++i) { for(size_t j = 0; j < 10; ++j) { cout << setw(2) << m_maze[i][j] << ','; } cout << '\b' << endl; } } private: //定义节点 class Node { public: int m_x; int m_y; Node(int x = 0, int y = 0) : m_x(x), m_y(y){} const Node operator+ (const Node& that)const { Node node; node.m_x = m_x + that.m_x; node.m_y = m_y + that.m_y; return node; } }; //查找 void searchPath(stack<Node>& path, const Node& start, const Node& end) { if(start.m_x == end.m_x && start.m_y == end.m_y) //走到终点 { if(path.size() < m_path.size() //当前路径更短 或 为第一个找到的路径 || m_path.empty()) m_path = path; return; } for( size_t i = 0; i < 4; ++i) //遍历四个方向 { Node nextNode = start + offset[i]; //加上偏移量 if(isCanGo(start, nextNode)) //如果可以通过 { m_maze[nextNode.m_x][nextNode.m_y] = m_maze[start.m_x][start.m_y] + 1; path.push(nextNode); //节点入栈 searchPath(path, nextNode, end); //递归查找 path.pop(); //弹出栈顶 } } } //判断start到next能否走通 bool isCanGo(const Node& start, const Node& next)const { int x = next.m_x, y = next.m_y; int preValue = m_maze[start.m_x][start.m_y]; //节点值 if(x < 0 || x > 9 || y < 0 || y > 9 //越界 || -1 == m_maze[x][y]) //墙 return false; if(0 == m_maze[x][y]) //可以走 return true; else return preValue+1 < m_maze[x][y]; //走过的点 } stack<Node> m_path; //存储最短路径 stack<Node> m_tempPath; //存储临时路径 Node m_start; //迷宫入口 Node m_end; //迷宫出口 static int m_maze[10][10]; //迷宫 static Node offset[4]; //四个方向偏移量 }; int Maze::m_maze[][10] = { { 0, 0, 0, 0,-1, 0, 0, 0, 0, 0}, { 0,-1,-1, 0, 0, 0, 0,-1, 0, 0}, { 0, 0,-1, 0,-1, 0, 0,-1, 0,-1}, { 0, 0,-1, 0,-1, 0, 0,-1, 0,-1}, { 0, 0, 0, 0,-1,-1, 0,-1, 0, 0}, { 0, 0,-1, 0, 0, 0, 0, 0, 0, 0}, { 0,-1, 0, 0,-1, 0,-1,-1, 0, 0}, { 0, 0, 0,-1, 0, 0, 0,-1, 0,-1}, {-1, 0, 0,-1, 0, 0, 0,-1, 0,-1}, { 0, 0, 0, 0, 0, 0, 0, 0, 0,-1}}; Maze::Node Maze::offset[] = {Node(-1, 0), Node(1, 0), Node(0, -1), Node(0, 1)}; int main(void) { Maze maze(2, 1, 1, 8); maze.searchPath(); maze.printPath(); maze.printMaze(); return 0; }结果如下:(坐标后数字为当前走过节点数)
原文地址:http://blog.csdn.net/liyuan_669/article/details/39457477