图及图的搜索算法-深度优先搜索

从地图上从一点到另一点,能不能找到一条路径。

#include "stdafx.h"

//网格 二维数组

//深度优先搜索需要注意
//搜索方向相对比较重要
//地图之间相对简单,相对位置相对固定
//

//深度优先搜索
//1、准备二维数组来表示地图
#define MAP_ROW 10
#define MAP_COL 10

//2、准备方向
enum Path_Dir{ p_up, p_left, p_down, p_right };

//3、准备表示路径点的类型
struct MyPoint {
	int row, col;
};

//4、准备一个数据结构来保存寻过的路径
#include<stack>
using std::stack;

//5、准备一个辅助数组
struct PathNode {
	bool isFind;	//表示该路径节点是否被访问
	int val;		//保存资源数组中的数值
	Path_Dir dir;	//表示该路径节点的搜索方向(下一个行进方向)
};

//10、准备一个用来检测是否越界及可以通行的函数
bool isMove(PathNode p[][MAP_COL], int row, int col) {
	if (row >= MAP_ROW || row < 0 || col < 0 || col >= MAP_COL) {
		return false;
	}
	//下一个节点不可行或被访问过
	if (p[row][col].val != 0 || p[row][col].isFind) {
		return false;
	}
	return true;
}

int _tmain(int argc, _TCHAR* argv[])
{
	int arr[MAP_ROW][MAP_COL]=
	{
		{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
		{ 1, 0, 0, 1, 0, 0, 0, 0, 0, 1 },
		{ 1, 1, 0, 1, 0, 1, 1, 1, 0, 1 },
		{ 1, 1, 0, 1, 0, 1, 1, 1, 0, 1 },
		{ 1, 1, 0, 0, 0, 1, 1, 1, 0, 1 },
		{ 1, 1, 0, 1, 0, 1, 1, 1, 0, 1 },
		{ 1, 1, 0, 1, 0, 0, 0, 0, 0, 1 },
		{ 1, 1, 0, 1, 0, 1, 1, 1, 0, 1 },
		{ 1, 0, 0, 1, 0, 1, 1, 1, 0, 1 },
		{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },

	};

	//5、准备一个辅助数组
	PathNode pathArr[MAP_ROW][MAP_COL];
	for (int i = 0; i < MAP_ROW; ++i){
		for (int j = 0; j < MAP_COL; ++j) {
			pathArr[i][j].isFind = false;
			pathArr[i][j].val = arr[i][j];
			pathArr[i][j].dir = p_up;
		}
	}

	//6、准备起点和终点
	MyPoint beginPoint = { 1, 1 };
	MyPoint endPoint = { 8, 8 };

	//7、起点压入容器适配器 栈
	stack<MyPoint> st;
	st.push(beginPoint);

	//8、准备一个辅助的坐标点
	MyPoint currentPoint = beginPoint;	//表示当前点

	//9、搜索路径
	while (true) {	//无法确定搜索次数
		switch (pathArr[currentPoint.row][currentPoint.col].dir)	//判断当前待搜索点的行进方向
		{
		case p_up:
			//可以通过和不可以通过都要更改下一次搜索方向
			pathArr[currentPoint.row][currentPoint.col].dir = p_left;
			if (isMove(pathArr, currentPoint.row - 1, currentPoint.col)) {
				//可以通过
				pathArr[currentPoint.row][currentPoint.col].isFind = true;	//标记已经访问
				MyPoint tempPoint = { currentPoint.row - 1, currentPoint.col };
				st.push(tempPoint);
				currentPoint = tempPoint;
			}
			break;
		case p_left:
			pathArr[currentPoint.row][currentPoint.col].dir = p_down;
			if (isMove(pathArr, currentPoint.row, currentPoint.col - 1)) {
				//可以通过
				pathArr[currentPoint.row][currentPoint.col].isFind = true;	//标记已经访问
				MyPoint tempPoint = { currentPoint.row, currentPoint.col - 1 };
				st.push(tempPoint);
				currentPoint = tempPoint;
			}
			break;

		case p_down:
			pathArr[currentPoint.row][currentPoint.col].dir = p_right;
			if (isMove(pathArr, currentPoint.row + 1, currentPoint.col)) {
				//可以通过
				pathArr[currentPoint.row][currentPoint.col].isFind = true;	//标记已经访问
				MyPoint tempPoint = { currentPoint.row + 1, currentPoint.col };
				st.push(tempPoint);
				currentPoint = tempPoint;
			}
			break;
		case p_right:	
			if (isMove(pathArr, currentPoint.row, currentPoint.col + 1)) {
				//可以通过
				pathArr[currentPoint.row][currentPoint.col].isFind = true;	//标记已经访问
				MyPoint tempPoint = { currentPoint.row, currentPoint.col + 1 };
				st.push(tempPoint);
				currentPoint = tempPoint;
			}
			else {	//并不是在有方向需要如此做,而是在示例中右是最后一个方向,所以在最后一个方向需要如此
				//需要在退栈之前把栈顶元素改为已访问
				MyPoint tempPoint = st.top();
				pathArr[tempPoint.row][tempPoint.col].isFind = true;

				st.pop();	//退栈
				if (!st.empty())
					currentPoint = st.top();	//得到新的栈顶
			}
			break;
		}
		//搜索结束条件
		if (currentPoint.row == endPoint.row && currentPoint.col == endPoint.col) {	//找到路径
			break;
		}
		if (st.empty()) {	//栈为空,没有搜索路径
			break;
		}
	}

	{
		while (!st.empty()) {
			MyPoint pos = st.top();
			printf("row = %d,col = %d\n", pos.row, pos.col);
			st.pop();
		}
	}
	return 0;
}

结果截图:
结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

海螺蜜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值