从地图上从一点到另一点,能不能找到一条路径。
#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;
}
结果截图: