一起学算法,第四章:深度寻路算法

7 篇文章 0 订阅
3 篇文章 0 订阅

废话不多说,直接开搞

1.看图
先看图
在这里插入图片描述

让起点上的小人从起点一直到终点,看图看不了多少直接看方法

2.方法
1.走的方法
1.1按照上,左,下,右逆时针方向行走
1.2总不能回头走吧,所以将走过的路径标为已走过(,下次就不会走了

2.遇到什么不能走
2.1有障碍(图中有颜色部分)
2.2死胡同(图中箭头所指),在这里不管是上方已经被标记已走过,还是左,下,右都是障碍。所以我们需要利用栈后入先出的原理,将走过的路径入栈,遇到这种情况就出栈直到岔路口。

~详细过程在代码注释中,所以下面请看代码
3.代码
首先先准备一个栈(MyStack.h):
这里我采用的是C++的写法

#include<iostream>
#include<stdlib.h>
using namespace std;

template<class T>
class Stack
{
private:
	T * pBuff;           //内存段首地址
	int len;             //栈内元素
	int maxLen;          //当前栈内存大小
public:
	Stack()
	{
		pBuff = NULL;
		len = maxLen = NULL;
	}
	~Stack()
	{
		if (pBuff)
			delete[] pBuff;
		pBuff = NULL;
		len = maxLen = NULL;
	}
	//出栈
	void Pop()
	{
		len--;
	}
	//入栈
	void Push(const T& Data);
	//是否为空
	bool IsEmpty()
	{
		return (pBuff == NULL);
	}
	//得到栈顶元素
	T getBuff()
	{
		return pBuff[len - 1];
	}
};

//入栈
template<class T>
void Stack<T>::Push(const T& Data)
{
	if (len >= maxLen)
	{
		//1.首先要开辟一个内存
		//1.1计算内存大小
		maxLen = maxLen + (((maxLen >> 1) > 1) ? (maxLen>>1) : 1);
		T * pTemp = new T[maxLen];//这里新的内存段要比原来内存要大
		//2.将pBuff拷贝到pTemp中去
		if (pBuff)
		{
			memcpy(pTemp, pBuff, sizeof(T)* len);
			delete[] pBuff;
		}
		//3.pBuff指向pTemp 
		//这个时候的pTemp比原来的pBuffer内存要大也能更好的传递数据
		pBuff = pTemp;
		
	}	
	//4.插入数据
	pBuff[len++] = Data;
}

下面来看main函数

#include"MyStack.h"
#define ROW 10
#define COL 10


struct MyPoint
{
	int x;
	int y;
};
enum  direct{Up,Left,Down,Right};

struct TestMap
{
	int dir;     //方向(枚举)
	bool IsFind; //判断走没走过
};

int main()
{
	//1.寻路前的准备
	//1.1首先创建一个地图
	int Map[ROW][COL] = {//这里的1表示障碍,0表示可以走的路
		1,1,1,1,1,1,1,1,1,1,
		1,0,1,1,1,1,1,1,1,1,
		1,0,1,1,1,1,1,1,1,1,
		1,0,1,1,1,1,1,1,1,1,
		1,0,1,1,1,1,1,1,1,1,
		1,0,0,0,0,0,0,1,1,1,
		1,0,1,1,1,1,0,1,1,1,
		1,0,1,1,1,1,0,1,1,1,
		1,0,1,1,1,1,0,0,0,1,
		1,1,1,1,1,1,1,1,1,1,
	};
	//1.2初始化起点和终点 
	MyPoint begPos = { 1,1 };    //起点
	MyPoint endPos = { 8,8 };    //终点

	//1.3定义当前点和试探点
	MyPoint currectPos = begPos;      //当前点从起点开始
	MyPoint searchPos;

	
	//1.4准备一个测试地图(用于标记已走过)
	TestMap testMap[ROW][COL] = { 0 };
	testMap[currectPos.x][currectPos.y].IsFind = true; //标记起始地点已经走过


	//1.5开栈
	Stack<MyPoint> stack;
	stack.Push(begPos);            //起点入栈
	bool IsFind;
	//2.开始寻路
	while (1)
	{
		searchPos = currectPos;
		//根据当前点来判断方向
		switch(testMap[currectPos.x][currectPos.y].dir)
		{
		case Up:			
			searchPos.y--;                          //向上y做减减运算
			testMap[currectPos.x][currectPos.y].dir++;//试探点换方向

			//判断能不能走
			if (Map[searchPos.x][searchPos.y] == 0//没有障碍
				&& testMap[searchPos.x][searchPos.y].IsFind == false)//没走过
			{
				//能走
				currectPos = searchPos;  //当前点等于试探点
				//坐标入栈
				stack.Push(searchPos);
				//标记已走过
				testMap[searchPos.x][searchPos.y].IsFind = true ;
			}					
			break;
		case Left:
			searchPos.x--;                          //向上y做减减运算
 			testMap[currectPos.x][currectPos.y].dir++;//试探点换方向

			//判断能不能走
			if (Map[searchPos.x][searchPos.y] != 1//没有障碍
				&& testMap[searchPos.x][searchPos.y].IsFind == false)//没走过
			{
				//走
				currectPos = searchPos;  //当前点等于试探点
				//坐标入栈
				stack.Push(searchPos);
				//标记已走过
				testMap[searchPos.x][searchPos.y].IsFind = true;
			}
			break;
		case Down:
			searchPos.y++;                          //向上y做减减运算
			testMap[currectPos.x][currectPos.y].dir++;//试探点换方向

			//判断能不能走
			if (Map[searchPos.x][searchPos.y] != 1//没有障碍
				&& testMap[searchPos.x][searchPos.y].IsFind == false)//没走过
			{
				//能走
				currectPos = searchPos;  //当前点等于试探点
				//坐标入栈
				stack.Push(searchPos);
				//标记已走过
				testMap[searchPos.x][searchPos.y].IsFind = true;
			}
			break;
		case Right:
			searchPos.x++;                          //向上y做减减运算
			testMap[currectPos.x][currectPos.y].dir++;//试探点换方向

			//判断能不能走
			if (Map[searchPos.x][searchPos.y] != 1//没有障碍
				&& testMap[searchPos.x][searchPos.y].IsFind == false)//没走过
			{
				//能走
				currectPos = searchPos;  //当前点等于试探点
				//坐标入栈
				stack.Push(searchPos);
				//标记已走过
				testMap[searchPos.x][searchPos.y].IsFind = true;
			}
			else//走到死胡同了
			{
				//回退
				//删除栈顶元素
				stack.Pop();
				//当前的点被栈顶元素赋值
				currectPos = stack.getBuff();

			}
			break;
			
		default:
			break;
		}

		//如果当前点等同于终点时退出循环
		if (currectPos.x == endPos.x && currectPos.y == endPos.y)
		{
			IsFind = true;
			break;
		}

		//如果整个地图中都没有终点的,那就会一直回退,知道栈里面的元素为空
		if (stack.IsEmpty())
		{
			break;
		}
	}

	if (IsFind)
	{
		printf("找到终点了");
	}
	else
	{
		printf("没找到");
	}

	return 0;
}

4.总结
我个人感觉寻路算法一定要好好研究,对于我这样的初学者来说,这其中包含的思想和逻辑都十分重要,学算法学的就是它的逻辑和思维。下面我还会学习介绍广度寻路和A星寻路。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值