寻路算法 --- 广度寻路算法

深度寻路:一个个去试,空旷地形

广度寻路:和深度寻路算法思想截然不同,不是一个个去试,而是依次展开:同样是从起点开始,看周围有哪些可以走的,依次去建立一棵树[ 只有四个方向:四叉树 ],总有一个地方,树会到达终点,最终这棵树会遍布整个地图,1. 到达终点,直接结束  2. 等整个地图都找完了,没有地方拓展了,再循环结束-> 树会记录从起点到每一个点的路径-> 可以找到多条路

不需要回退,一定能找到最佳路径 因为总是需要去拓展,循环次数会变得很多:消耗时间长,适合小地图,非空旷地形

注意:要弄一个容器去存储当前层,因为某一层可能不止一个,可能有好多个

#include <iostream>
#include <vector>
using namespace std;
//Y   竖着
#define ROWS  10
//X   横着
#define COLS  10
//4个方向都需要去找一遍-> 不需要有试探方向-> 辅助地图为bool类型 找过的不管,没找过的就去试一下
enum direct{ p_up, p_down, p_left, p_right };
class MyPoint{
public:
	int row, col;
	friend bool operator==(const MyPoint& p1, const MyPoint& p2);
};
bool operator==(const MyPoint& p1, const MyPoint& p2){
	if ((p1.row == p2.row) && (p1.col == p2.col)) return true;
	return false;
}

//准备一棵树
struct treeNode{
	MyPoint				pos;      //点
	treeNode*			pParent;  //指向父节点的指针
	vector<treeNode*>	child;	  //数组里存指向孩子节点指针-> 有多个孩子最多4个 具体不知道 动态数组有几个就加几个
	treeNode(){}
	~treeNode(){
		pos.row = 0;
		pos.col = 0;
		pParent = NULL;
		child.clear();
	}

};
treeNode* createTreeNode(int row, int col);    //创建点
//判断pos点能不能走,传入两个地图和点 能走返回ture,不能返回false
bool canWalk(int map[ROWS][COLS], bool pathMap[ROWS][COLS], MyPoint pos);


int main(){
	//地图
	int map[ROWS][COLS] = {
		{ 0, 1, 1, 1, 1, 1, 1, 0, 0, 0 },
		{ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1 },
		{ 0, 1, 1, 0, 1, 0, 1, 1, 1, 0 },
		{ 0, 0, 0, 0, 1, 0, 1, 1, 1, 0 },
		{ 0, 1, 1, 1, 1, 0, 1, 1, 1, 0 },
		{ 0, 0, 0, 0, 0, 0, 1, 1, 1, 0 },
		{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
		{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
		{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
		{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 }
	};
	//辅助地图
	bool pathMap[ROWS][COLS] = { 0 };          //都为0-> 都没有找过

	MyPoint begPos = { 0, 0 };//起点
	MyPoint endPos = { 0, 9 };//终点

	pathMap[begPos.row][begPos.col] = true;    //起点标记为走过
	treeNode* pRoot = NULL;//准备一棵树

	//起点成为树的根节点
	pRoot = createTreeNode(begPos.row, begPos.col);


	vector<treeNode*> buff;		//存储当前层-> 有当前层就有下一层 否则没办法从当前层转到下一层去
	buff.push_back(pRoot);      //当前层里是树的根节点-> 树的起点是当前层的第一个
	vector<treeNode*> nextBuff;	//存储下一层
	bool isFindEnd = false;
	treeNode* temp = NULL;
	while (1){
		nextBuff.clear();//清空下一层
		for (int i = 0; i < buff.size(); i++){//遍历当前层
			//找出 当前层的每一个buff[i] 所有相邻的能走的节点  存放到nextBuff中 并且 入树
			for (int j = 0; j < 4; j++){//判断能走还是不能走 每一个点只有4个方向-> 判断4个方向哪个能走哪个不能走
				temp = createTreeNode(buff[i]->pos.row, buff[i]->pos.col);    //创建新节点等于当前节点
				switch (j){
				case p_up:		temp->pos.row--; break;
				case p_down:	temp->pos.row++; break;
				case p_left:	temp->pos.col--; break;
				case p_right:	temp->pos.col++; break;
				}
				if (canWalk(map, pathMap, temp->pos)){//为真能走 不为真不能走直接释放
					//标记走过
					pathMap[temp->pos.row][temp->pos.col] = true;
					//入树
					buff[i]->child.push_back(temp);	//temp成为buff[i]的子
					temp->pParent = buff[i];		//buff[i]成为temp的父
#if 1
					if (endPos == temp->pos){       //找到了就结束-> 只结束了j循环
						isFindEnd = true;
						break;
					}
#endif
					//存入nextBuff中
					nextBuff.push_back(temp);
				}
				else{//不能走
					delete temp; //释放
					temp = NULL;
				}
			}// end of for(j)
			if (isFindEnd) break;//结束i循环    
		}// end of for(i)
		if (isFindEnd) break;    //结束while循环
		if (0 == nextBuff.size()) break;//地图都遍历完了-> 找不到下一个就结束
		buff = nextBuff;//切换到下一层去
	}//end of while(1)

	if (isFindEnd){
		cout << "找到终点啦!" << endl;
		while (temp){//输出路径
			cout << "("<<temp->pos.row << ","<< temp->pos.col << ") ";
			temp = temp->pParent;//temp要往上走
		}
		cout << endl;
	}

	while (1);
	return 0;
}


treeNode* createTreeNode(int row, int col){
	treeNode* pNew = new treeNode;
	memset(pNew, 0, sizeof treeNode);    //清空
	pNew->pos.row = row;            
	pNew->pos.col = col;
	return pNew;
}
//判断pos点能不能走,能返回ture,不能返回false
bool canWalk(int map[ROWS][COLS], bool pathMap[ROWS][COLS], MyPoint pos){
	//越界-> 超出数组范围
	if (pos.row < 0 || pos.row >= ROWS || pos.col < 0 || pos.col >= COLS) return false;
	//是障碍物
	if (1 == map[pos.row][pos.col]) return false;
	//走过
	if (true == pathMap[pos.row][pos.col]) return false;
	return true;
}

 

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qiuqiuyaq

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值