一、相关概念:
深度寻路算法:
一个点一条线去找,死胡同则回退
不一定能找到最短路径
优点:
没有循环
缺点:
不一定能找到最短路径广度寻路算法:
多线并行查找,不需要回退,一定能找到最短路径
优点:
一定能找到最短路径
不需要回退
缺点:
循环复杂,有些时候会很慢应用场景区分:
开阔,大地图 用深度
小地图 用广度
二、代码实现
1.准备工作
① 辅助地图只需要注明->是否走过即可
②关注treeNode 有parent(用于最后打印出路径用)和child(用一个vector存储)
③额外开两个存放treeNode*的动态数组->切换层用,以及遍历用
④语法细节:struct treeNode内部成员需要写treeNode*类型
#include<iostream> #include<vector> using namespace std; #define ROWS 10 #define COLS 10 enum dir {UP,RIGHT,DOWN,LEFT}; //辅助地图只需要bool->存放是否走过即可 bool pathMap[ROWS][COLS] = { 0 };//0表示没有走过 //地图 bool Map[ROWS][COLS]= { { 0, 1, 0, 0, 0, 0, 0, 1, 0, 0 }, { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 }, { 0, 0, 0, 1, 0, 1, 0, 1, 0, 1 }, { 0, 1, 0, 0, 0, 1, 0, 1, 0, 0 }, { 0, 1, 0, 1, 0, 0, 0, 1, 1, 0 }, { 0, 1, 0, 1, 0, 1, 0, 0, 1, 0 }, { 0, 1, 0, 0, 0, 1, 0, 0, 0, 0 }, { 0, 1, 0, 1, 0, 0, 0, 1, 1, 0 }, { 0, 1, 0, 1, 0, 1, 0, 1, 0, 0 }, { 0, 0, 0, 1, 0, 1, 0, 1, 1, 0 } }; //描述坐标的struct struct Point { int row; int col; bool operator== (const Point& p) { return (p.col == col && p.row == row); } }; //树的结点类型 struct treeNode { struct Point data; struct treeNode* pParent; vector<struct treeNode*>pChild; }; vector<struct treeNode*> currentLayer; vector<struct treeNode*> nextLayer; struct Point BeginPos = { 0,0 }; struct Point EndPos = { 9,9}; treeNode* createNode(const struct Point& t) { treeNode* pNew = new treeNode; memset(pNew, 0, sizeof(treeNode)); pNew->data = t; return pNew; } bool CanWalk(const Point& s, bool pathMap[ROWS][COLS],bool Map[ROWS][COLS]) { //1.越界不能走 if (s.row < 0 || s.col < 0 || s.col >= COLS || s.row >= ROWS) return false; //2.有墙(1)不能走 if (pathMap[s.row][s.col] == 1)return false; //3.走过(1)不能走 if (Map[s.row][s.col] == 1)return false; return 1;//其余情况均可走 }
2.core code
①注意,每次进入switch之前,都要更新searchNode为当前位置!!!否者下次循环的searchNode会和预想的位置不太一样
②找到一个符合的->除了放入nextLayer之外,还要进行相应的parent赋值以及child的赋值
双向都要进行相应的赋值
int main() { struct treeNode *pRoot = createNode(BeginPos); currentLayer.push_back(pRoot); bool isFind = false; struct treeNode* pTemp=nullptr; struct Point searchNode; while (!isFind) { nextLayer.clear(); for (int i = 0; i < currentLayer.size(); i++) { pathMap[currentLayer[i]->data.row][currentLayer[i]->data.col] = 1;//标记当前层all Node已经走过 for (int j = 0; j < 4; j++) { searchNode = currentLayer[i]->data;//every time enter the switch ,first reset the searchNode!!! switch (j) { case UP: searchNode.row--; break; case RIGHT:searchNode.col++; break; case DOWN:searchNode.row++; break; case LEFT:searchNode.col--; break; } if (CanWalk(searchNode, pathMap, Map)) { pTemp = createNode(searchNode); currentLayer[i]->pChild.push_back(pTemp); nextLayer.push_back(pTemp); pTemp->pParent=currentLayer[i];//注意双向设置 if (EndPos == pTemp->data) { isFind = true; break; } } } if (isFind == true)break; } if (nextLayer.size() == 0)break;//无路可走->break currentLayer = nextLayer;//切换层 } if (isFind) { cout << "找到啦!" << endl; while (pTemp) { cout << "(" << pTemp->data.row << "," << pTemp->data.col << ")" << endl; pTemp = pTemp->pParent; } } return 0; }
红色->为寻找的最优路径