数据结构学习第十八课(寻路算法之深度寻路)

寻路算法

/*
寻路算法:
找路径

1 深度寻路:不一定能找到最短路径,回退,循环较少,步骤简单,适用于空旷地图;只能走直线
2 广度寻路:一定能找到最短路径,不需要回退,循环较多,步骤复杂,适用于较小的复杂地图;只能走直线
3 A星寻路:一定能找到最短路径,不需要回退,循环较少,但需要提前设计好代价;只能走斜线
*/
1,深度寻路
1.1头文件
#pragma once
#include<string.h>
template<typename T>
class MyStack
{
private:
	T* pRoot;
	int len;
	int maxLen;
public:
	MyStack() 
	{
		pRoot = NULL;
		len = 0;
		maxLen = 0;
	}
	~MyStack()
	{
		if (pRoot)
		{
			delete[] pRoot;
		}
		pRoot = NULL;
		len = 0;
		maxLen = 0;
	}
	//入栈
	void push(const T& data);
	//判空
	bool isEmpty()const
	{
		return (len == 0);
	}
	//出栈
	void pop() { len--; };
	//获取栈顶元素
	T GetTop()const
	{
		return pRoot[len - 1];
	}

};

template<typename T>
void MyStack<T>::push(const T& data)
{
	if (len <= maxLen)
	{
		maxLen = maxLen + (((maxLen >> 1) > 1) ? (maxLen >> 1) : 1);
		T* pTemp = new T[maxLen];
		memcpy(pTemp, pRoot, sizeof(T) * len);
		delete[] pRoot;
		pRoot = pTemp;
	}
	pRoot[len++] = data;

}

2.2源文件


/*
深度寻路思想:
1 记录当前点当前试探方向
试探方向顺序:一般:逆时针(上左下右) / 顺时针(上右下左);
2 记录当前点是否走过
2.1 每走过一步,入栈
2.2 需要回退的时候 死胡同时 回退
2.2.1 删除栈顶元素
2.2.2 跳到当前栈顶元素的位置
*/

#include<stdio.h>
#include<stack>
#include<graphics.h>
#include"Mystack.h"
#define SPACE 50
 
using namespace std;
#define ROW 12
#define COL 12
//地图中元素类型
enum type{p_road,p_wall};
//方向
enum dirc{p_up,p_down,p_left,p_right};
//描述一个点
struct Point
{
	int row;
	int col;
	bool operator==(const Point& p)
	{
		if (this->row == p.row && this->col == p.col)
		{
			return true;
		}
		return false;
	}
};
//辅助地图结点类型
struct pathNode
{
	int dir;//当前试探方向
	bool isFind;//是否走过
};
IMAGE wall, ren, road, pos;
void printMap(Point pos, int map[ROW][COL]);
void showMap(Point pos, int map[ROW][COL]);
int main()
{
	initgraph(COL * SPACE, ROW * SPACE, SHOWCONSOLE);
	loadimage(&wall, "wall.bmp", SPACE, SPACE, true);
	loadimage(&ren, "ren.bmp", SPACE, SPACE, true);
	loadimage(&road, "road.bmp", SPACE, SPACE, true);
	loadimage(&pos, "pos.bmp", SPACE/2, SPACE/2, true);
	
	
	//1 描述地图
	int map[ROW][COL] =
	{
		{1,1,1,1,1,1,1,1,1,1,1,1},
		{1,0,1,1,0,1,1,1,1,0,0,1},
		{1,0,1,1,0,0,0,1,1,0,1,1},
		{1,0,1,1,0,1,0,1,1,0,1,1},
		{1,0,1,1,0,1,0,1,1,0,1,1},
		{1,0,1,1,0,1,0,1,1,0,1,1},
		{1,0,1,1,0,1,0,0,1,0,1,1},
		{1,0,1,1,0,1,1,0,1,0,1,1},
		{1,0,0,0,0,1,1,0,1,0,1,1},
		{1,0,1,1,0,1,1,0,1,0,1,1},
		{1,0,1,1,0,1,1,0,0,0,1,1},
		{1,1,1,1,1,1,1,1,1,1,1,1}
	};
	//2 记录当前点当前试探方向,是否走过
	pathNode pathMap[ROW][COL] = { 0 };

	//3 起点 终点
	bool isFindEnd = false;
	Point begPos = { 1,1 };
	Point endPos = { 1,10 };

	//4 栈
	MyStack<Point> stack;

	//5 标记起点走过的,起点入栈
	stack.push(begPos);
	pathMap[begPos.row][begPos.col].isFind = true;
	//6 寻路
	Point curPos = begPos;
	Point serPos;
	while (1)
	{
		//6.1确定试探点
		serPos = curPos;//先将试探点设置为当前点
		switch (pathMap[curPos.row][curPos.col].dir)
		{
		case p_up:
			serPos.row--;//根据当前点当前试探方向,确定试探点
			//当前点当前试探方向改变
			pathMap[curPos.row][curPos.col].dir = p_down;
			if (pathMap[serPos.row][serPos.col].isFind == false &&//没走过
				map[serPos.row][serPos.col] == p_road)//有路
			{
				//能走
				//走
				curPos = serPos;
				//标记走过
				pathMap[curPos.row][curPos.col].isFind = true;
				//入栈
				stack.push(curPos);
			}
			break;
		case p_down:
			serPos.row++;//根据当前点当前试探方向,确定试探点
			//当前点当前试探方向改变
			pathMap[curPos.row][curPos.col].dir = p_left;
			if (pathMap[serPos.row][serPos.col].isFind == false &&//没走过
				map[serPos.row][serPos.col] == p_road)//有路
			{
				//能走
				//走
				curPos = serPos;
				//标记走过
				pathMap[curPos.row][curPos.col].isFind = true;
				//入栈
				stack.push(curPos);
			}
			break;
		case p_left:
			serPos.col--;//根据当前点当前试探方向,确定试探点
			//当前点当前试探方向改变
			pathMap[curPos.row][curPos.col].dir = p_right;
			if (pathMap[serPos.row][serPos.col].isFind == false &&//没走过
				map[serPos.row][serPos.col] == p_road)//有路
			{
				//能走
				//走
				curPos = serPos;
				//标记走过
				pathMap[curPos.row][curPos.col].isFind = true;
				//入栈
				stack.push(curPos);
			}
			break;
		case p_right:
			serPos.col++;//根据当前点当前试探方向,确定试探点
			if (pathMap[serPos.row][serPos.col].isFind == false &&//没走过
				map[serPos.row][serPos.col] == p_road)//有路
			{
				//能走
				//走
				curPos = serPos;
				//标记走过
				pathMap[curPos.row][curPos.col].isFind = true;
				//入栈
				stack.push(curPos);
			}
			else
			{
				//死胡同
				//删除栈顶元素
				stack.pop();
				//跳到当前栈顶元素
				curPos = stack.GetTop();
			}
			break;
		}
		printMap(curPos, map);
		showMap(curPos, map);
		//判断到没到终点
		if (curPos == endPos)
		{
			isFindEnd = true;
			break;
		}
		//判断是否回到起点
		if (stack.isEmpty())
			break;
	}
	if (isFindEnd)
	{
		printf("找到了终点!!!\n");
		while (!stack.isEmpty())
		{
			printf("(%d %d)", stack.GetTop().row,
				stack.GetTop().col);
			putimage(stack.GetTop().col * SPACE
				+SPACE/3,
				stack.GetTop().row * SPACE + SPACE / 3,
				&pos);
			stack.pop();
		}
		printf("\n");
	}
	else
	{
		printf("没找到终点!!!\n");
	}
	while (1);
	return 0;
}

void printMap(Point pos, int map[ROW][COL])
{
	system("cls");
	for (int i = 0; i < ROW; i++)
	{
		for (int j = 0; j < COL; j++)
		{
			if (pos.row == i && pos.col == j)
			{
				printf("人");
			}
			else if(p_road==map[i][j])
			{
				printf("  ");
			}
			else
			{
				printf("墙");
			}
		}
		printf("\n");
	}
}

void showMap(Point pos, int map[ROW][COL])
{
	for (int i = 0; i < ROW; i++)
	{
		for (int j = 0; j < COL; j++)
		{
			if (pos.row == i && pos.col == j)
			{
				putimage(j * SPACE, i * SPACE, &ren);
			}
			else if (p_road == map[i][j])
			{
				putimage(j * SPACE, i * SPACE, &road);
			}
			else
			{
				putimage(j * SPACE, i * SPACE, &wall);
			}
		}
		printf("\n");
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值