数据结构之深度寻路---地图寻路(栈实现)

版权声明:版权声明:本文章刊载的所有内容,包括文字、图片、音频、视频、软件、程序、以及网页版式设计等均归"江南、董少"所有! https://blog.csdn.net/qq_41453285/article/details/83276428

注:深度寻路用到的栈头文件以及.cpp文件
在我的资源中可下载或者Q:1286550014(免费)

深度寻路

原理:在地图中从一个点开始,从规定方向开始走,无障碍就继续走,数据压栈,如果有障碍就退一步,数据出栈,直至找到终点或无终点时,寻路结束。

一、头文件导入

#include "Stack.h"
//此头文件包含数据结构中的栈,栈用顺序表的形式实现,
//为自己实现的栈结构,里面包含各种函数方法

二、结构体、方向枚举、宏定义

#define ROW 8	//地图的行
#define COL 12	//地图的列

//一个枚举,存储寻路的四个方向,分别为上下左右
enum Dir {p_up,p_down,p_left,p_right};

//结构体,用于表示地图二维数组中的某一个点
typedef struct Node
{
	int x;
	int y;
}Node;

//一个辅助结构体,用于保存地图每一个点的信息
typedef struct PathNode
{
	int value;	//地点的值,0为可通路,1为不可通路
	Dir dir;	//地点的方向
	bool isFind;//一个值,判断当前点是否已经走过
}PathNode;

三、主函数的进入

//主地图的定义,包含了地图的信息
int arr[ROW][COL] = {
		{ 1,1,1,1,1,1,1,1,1,1,1,1 },
		{ 1,0,0,0,1,0,1,1,1,1,1,1 },
		{ 1,1,1,0,1,0,0,0,0,0,1,1 },
		{ 1,1,1,0,1,0,1,1,1,0,1,1 },
		{ 1,1,1,0,1,0,1,1,1,0,1,1 },
		{ 1,1,1,0,1,0,1,1,1,0,1,1 },
		{ 1,0,0,0,0,0,1,1,1,0,0,1 },
		{ 1,1,1,1,1,1,1,1,1,1,1,1 },
	};
	
	//因为不能对主地图进行各种操作,所以定义一个辅助地图,
	//用于后面进行各种操作,并通过for循环对辅助地图进行初始化
	PathNode pathNode[ROW][COL];
	for (int i = 0; i < ROW; i++)
	{
		for (int j = 0; j < COL; ++j)
		{
			pathNode[i][j].value = arr[i][j];//将地图的每个点值放入辅助地图
			pathNode[i][j].isFind = false;//每个地图点都设置为未访问过
			pathNode[i][j].dir = p_up;	//每个点的默认寻找方向向上
		}
	}
//定义地图的初始化起点与终点
Node beginNode = { 1,1 };
Node endNode = { 6,10 };
	
//定义一个栈,用于保存寻找到的地图信息点
Stack<Node>* st=new Stack<Node>(100);
//先将起点压入栈中
st->PushStack(beginNode);

//定义一个辅助点,用于在地图中进行各种寻路操作
Node tempNode = st->GetTop();
//定义一个死循环,进行寻路操作,操作通过点查找实现,当找到一个可行点的时候就入栈,
//路不通时就出栈,并分别从上下左右四个方向进行查找,我们规定查找的顺序为:上->下->左->右
//当一个点上下左右都找不到时就将此点出栈
while (true)
	{
		//通过方向进行查找
		switch (pathNode[tempNode.x][tempNode.y].dir)
		{
		//先判断向上查找,下面的下和左亦同,但是向右需单独判断
		case p_up:
			//不论下一点是否可访问,先将此点的方向设置为向下,用于不能访问后重新进行寻路
			pathNode[tempNode.x][tempNode.y].dir = p_down;
			//如果上一点可访问
			if (pathNode[tempNode.x - 1][tempNode.y].isFind == false &&
				pathNode[tempNode.x - 1][tempNode.y].value == 0)
			{
				//将当前点设置为以访问过
				pathNode[tempNode.x][tempNode.y].isFind = true;
				//将新点入栈,并将辅助点设置为新点
				Node temp = { tempNode.x - 1,tempNode.y };
				st->PushStack(temp);
				tempNode = temp;
			}
			break;
		case p_down:
			pathNode[tempNode.x][tempNode.y].dir = p_left;
			if (pathNode[tempNode.x + 1][tempNode.y].isFind == false &&
				pathNode[tempNode.x + 1][tempNode.y].value == 0)
			{
				pathNode[tempNode.x][tempNode.y].isFind = true;
				Node temp = { tempNode.x + 1,tempNode.y };
				st->PushStack(temp);
				tempNode = temp;
			}
			break;
		case p_left:
			pathNode[tempNode.x][tempNode.y].dir = p_right;
			if (pathNode[tempNode.x][tempNode.y - 1].isFind == false &&
				pathNode[tempNode.x][tempNode.y - 1].value == 0)
			{
				pathNode[tempNode.x][tempNode.y].isFind = true;
				Node temp = { tempNode.x,tempNode.y - 1 };
				st->PushStack(temp);
				tempNode = temp;
			}
			break;
		case p_right:
			if (pathNode[tempNode.x][tempNode.y + 1].isFind == false &&
				pathNode[tempNode.x][tempNode.y + 1].value == 0)
			{
				pathNode[tempNode.x][tempNode.y].isFind = true;
				Node temp = { tempNode.x,tempNode.y + 1 };
				st->PushStack(temp);
				tempNode = temp;
			}
			//如果上下左右都走不通,说明此点作废,需要将此点出栈,并进行重新寻路
			else
			{
				//得到这个点,并将这个点设置为已访问过,并将其出栈
				Node temp = st->GetTop();
				pathNode[temp.x][temp.y].isFind = true;
				st->PopStack();
				if (!st->isEmpty())
				{
					//出栈后重新获得辅助点
					tempNode = st->GetTop();
				}
			}
			break;
		}
		//如果找到终点了,就退出while循环
		if (tempNode.x == endNode.x
			&&tempNode.y == endNode.y)
		{
			break;
		}
		//如果栈为空了,说明寻路失败,也退出while循环
		if (st->isEmpty())
		{
			break;
		}
	}

四、打印寻路信息

当以上所有事务都完成,且寻路成功后,就可以从栈中获取我们所要的寻路信息

//循环打印
while (!st->isEmpty())
	{
		printf("row=%d,col=%d\n", st->GetTop().x, st->GetTop().y);
		st->PopStack();
	}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_41453285/article/details/83276428
今日推荐