C++ BFS广度优先搜索

广度优先搜索

根据优先级进行广度搜索

通过回溯找到最短路径

代码实现

1.真实地图

//真实地图
#define MAP_ROW 6
#define MAP_COL 8

2.方向

//方向
enum PathDir
{
	P_UP,
	P_LEFT,
	P_DOWN,
	P_RIGHT
};

3.坐标

//坐标
struct MyPoint
{
	int row;
	int col;
};

4.地图数组节点结构

//地图节点结构
struct PathData
{
	PathDir dir;
	int val;
	bool isFind;
};

5.树形结构 -节点

//树形结构
struct MyPathNode
{
	MyPoint pos; //数据域 - 坐标
	MyPathNode * pParent; //父节点指针
	vector<MyPathNode *> pChild; //子节点指针数组
};

6.判断函数

//判断函数
bool isCheckPoint(MyPoint const& pos,PathData arr[][MAP_COL])
{
	// 判断越界
	if (pos.row >= 0 && pos.col >= 0 && pos.row < MAP_ROW && pos.col < MAP_COL)
	{
        //没越界
		//第二个判断 空地且没有走过
		if (arr[pos.row][pos.col].val == 0 && arr[pos.row][pos.col].isFind == false)
		{
			//空地 并且没有走过
			return true;
		}
	}
	return false;
}

7.销毁函数

//树的销毁函数
void clearTree(MyPathNode *& root)
{
	if (root)
	{
		for (size_t i = 0; i < root->pChild.size(); ++i)
		{
			clearTree(root->pChild[i]); //递归孩子
		}
		delete root;
		root = nullptr;
	}
	//没有节点自动结束递归
}

8.创建辅助数组

	int arrMap[MAP_ROW][MAP_COL] =
	{
		{ 0, 0, 0, 0, 0, 0, 0, 0 },
		{ 0, 0, 0, 0, 0, 0, 0, 0 },
		{ 0, 1, 1, 1, 0, 0, 0, 0 },
		{ 0, 0, 0, 0, 0, 1, 0, 0 },
		{ 0, 0, 0, 0, 0, 1, 0, 0 },
		{ 0, 0, 0, 0, 0, 0, 0, 0 },
	};

9.起点和终点

	//起点和终点
	MyPoint beginPoint = { 1, 1 };
	MyPoint endPoint = { 4,6};

10.寻路树形结构数组

	//准备两个寻路用的树形结构数组
	vector<MyPathNode *> parentTable;
	vector<MyPathNode *> childTable;

11.石头

//准备石头
	MyPoint tempPoint;

12.开始寻路

//开始寻路
	while (true)
	{
		//根据父节点元素做循环 四个方向
		//外层 - 父节点 
		for (int i = 0; i < (int)parentTable.size(); ++i)
		{
			for (int j = 0; j < 4; ++j)
			{
				//石头探路
				tempPoint = parentTable[i]->pos; //坐标
				switch (j)
				{
				case P_UP:
					tempPoint.row--;
					break;
				case P_LEFT:
					tempPoint.col--;
					break;
				case P_RIGHT:
					tempPoint.col++;
					break;
				case P_DOWN:
					tempPoint.row++;
					break;
				default:
					break;
				}
				//下一步位置确定
				if (isCheckPoint(tempPoint,PathArr))
				{
					//添加 准备节点尾插
					MyPathNode * tempNode = new MyPathNode;
					tempNode->pos = tempPoint; //位置赋值

					//*关联父子关系
					tempNode->pParent = parentTable[i];
					parentTable[i]->pChild.push_back(tempNode);
					//设置已访问
					PathArr[tempPoint.row][tempPoint.col].isFind = true;
					//*把父节点数组所有可通行的加入子节点表
					childTable.push_back(tempNode);
					//判断当前节点是否为终点
					if (tempPoint.row == endPoint.row&&tempPoint.col == endPoint.col)
					{
						//终点找到了 - 打印路径 - 遍历用指针
						MyPathNode * pNode = tempNode;
						//往上找父节点
						while (pNode)
						{
							//打印
							printf("row = %d, col = %d\n", pNode->pos.row, pNode->pos.col);
							//步长移动
							pNode = pNode->pParent;
						}
						//结束寻路 -跳出五层循环
						goto OVER;
					}
				}
			}
		}
		if (childTable.size() == 0)//没路了
		{
			cout << "找不到终点" << endl;
			goto OVER;
		}
		//循环结束 - 说明父节点指针遍历完了
		parentTable = childTable; //父子交接
		//清除子表
		childTable.clear();
	}
OVER:

总体

Point = { 1, 1 };
	MyPoint endPoint = { 4,6};

	//辅助数组
	PathData PathArr[MAP_ROW][MAP_COL];
	//成员初始化
	for (int i = 0; i < MAP_ROW; ++i)
	{
		for (int j = 0; j < MAP_COL; j++)
		{
			PathArr[i][j].val = arrMap[i][j];
			PathArr[i][j].isFind = false; 
			PathArr[i][j].dir = P_UP; //从上开始
		}
	}
	//起点且根节点已走过
	PathArr[beginPoint.row][beginPoint.col].isFind = true; 

	//准备一个树形结构
	MyPathNode *pRoot = nullptr;
	pRoot = new MyPathNode;
	pRoot->pos = beginPoint;
	pRoot->pParent = nullptr;
		//准备两个寻路用的树形结构数组
	vector<MyPathNode *> parentTable;
	vector<MyPathNode *> childTable;


	// 父节点数组添加起点
	parentTable.push_back(pRoot);


	//准备石头
	MyPoint tempPoint;
	//开始寻路
	while (true)
	{
		//根据父节点元素做循环 四个方向
		//外层 - 父节点 
		for (int i = 0; i < (int)parentTable.size(); ++i)
		{
			for (int j = 0; j < 4; ++j)
			{
				//石头探路
				tempPoint = parentTable[i]->pos; //坐标
				switch (j)
				{
				case P_UP:
					tempPoint.row--;
					break;
				case P_LEFT:
					tempPoint.col--;
					break;
				case P_RIGHT:
					tempPoint.col++;
					break;
				case P_DOWN:
					tempPoint.row++;
					break;
				default:
					break;
				}
				//下一步位置确定
				if (isCheckPoint(tempPoint,PathArr))
				{
					//添加 准备节点尾插
					MyPathNode * tempNode = new MyPathNode;
					tempNode->pos = tempPoint; //位置赋值

					//*关联父子关系
					tempNode->pParent = parentTable[i];
					parentTable[i]->pChild.push_back(tempNode);
					//设置已访问
					PathArr[tempPoint.row][tempPoint.col].isFind = true;
					//*把父节点数组所有可通行的加入子节点表
					childTable.push_back(tempNode);
					//判断当前节点是否为终点
					if (tempPoint.row == endPoint.row&&tempPoint.col == endPoint.col)
					{
						//终点找到了 - 打印路径 - 遍历用指针
						MyPathNode * pNode = tempNode;
						//往上找父节点
						while (pNode)
						{
							//打印
							printf("row = %d, col = %d\n", pNode->pos.row, pNode->pos.col);
							//步长移动
							pNode = pNode->pParent;
						}
						//结束寻路 -跳出五层循环
						goto OVER;
					}
				}
			}
		}
		if (childTable.size() == 0)//没路了
		{
			cout << "找不到终点" << endl;
			goto OVER;
		}
		//循环结束 - 说明父节点指针遍历完了
		parentTable = childTable; //父子交接
		//清除子表
		childTable.clear();
	}
OVER:
	//树的释放
	clearTree(pRoot);

	system("pause");
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值