栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++ BFS广度优先搜索

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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 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 parentTable;
	vector 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 = %dn", 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 parentTable;
	vector 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 = %dn", 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;
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/920838.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号