深度优先搜索也称深度寻路
规则:沿一个方向行走,走到了岔路口有选择一个方向进行前进 若碰到死胡同 退到上一个岔路口重新选择方向 走过的路不会再走 一次只能走一个点
1.准备地图(二维数组 用1表示障碍 不可通行 用0表示可以通行
1 #define MAP_ROW 10 2 #define MAP_COL 10
2.准备方向
1 enum Path_Dir{p_up,p_down,p_left,p_right};
3.准备一个栈用来保存搜索中可以行走的路径点信息
1 #pragma one
2 template<typename T>
3 class CMyStack
4 {
5 T *pBuff;
6 size_t len;
7 size_t maxSize;
8 public:
9 CMyStack();
10 ~CMyStack();
11 void clear();
12 public:
13 void push(T const& elem);
14 void pop();
15 T const& getTop() const{ return pBuff[len - 1]; }
16 bool empty() const{ return len == 0; }
17 };
18
19 template<typename T>
20 void CMyStack<T>::pop()
21 {
22 --len;
23 }
24
25 template<typename T>
26 void CMyStack<T>::push(T const& elem)
27 {
28 if (len>=maxSize)
29 {
30 maxSize = maxSize + ((maxSize >> 1) > 1 ? (maxSize >> 1) : 1);
31 T *tempBuff = new T[maxSize];
32 for (size_t i = 0; i < len; i++)
33 tempBuff[i] = pBuff[i];
34 if (pBuff != nullptr)
35 delete[] pBuff;
36 pBuff = tempBuff;
37 }
38 pBuff[len++] = elem;
39 }
40
41 template<typename T>
42 void CMyStack<T>::clear()
43 {
44 if (pBuff!=nullptr)
45 {
46 delete[] pBuff;
47 pBuff = nullptr;
48 len = maxSize = 0;
49 }
50 }
51
52
53 template<typename T>
54 CMyStack<T>::~CMyStack()
55 {
56 clear();
57 }
58
59 template<typename T>
60 CMyStack<T>::CMyStack()
61 {
62 pBuff = nullptr;
63 len = maxSize = 0;
64 }
4.准备一个结构用来保存每一个路径点再二维数组的行列值
1 struct MyPoint 2 { 3 int row, col; 4 };
5.准备一个辅助数组(1.资源地图数组不能变 2.对资源地图要进行数组标记)
1 struct PathNode
2 {
3 int val;//保存原始资源的路径点信息
4 Path_Dir dir;//当前路径点的方向标记
5 bool isFind;//当前路径点是否被访问过
6 };
准备一个函数 用来判断参数坐标是否可以通行
1 bool IsMove(PathNode p[][MAP_COL],int row,int col)
2 {
3 if (row < 0 || row >= MAP_ROW || col < 0 || col >= MAP_COL)
4 return false;//如果越界,不需要进行位置的判断
5 if (p[row][col].val != 0 || p[row][col].isFind == true)
6 return false;//表示当前行列的元素要么是障碍,要么已经被访问过,不能通行
7 return true;
8 }
第六步设置访问结点
1 PathNode pathArr[MAP_ROW][MAP_COL];
2 for (int i = 0; i < MAP_ROW; ++i)
3 {
4 for (int j = 0; j < MAP_COL; ++j)
5 {
6 pathArr[i][j].val = mapArr[i][j];
7 pathArr[i][j].isFind = false;//表示地图中的每一个节点都没有被访问过
8 pathArr[i][j].dir = p_up;//表示给地图中的每一个节点都设定一个初始方向
9 }
10 }
第七步设置起点和终点
1 MyPoint beginPoint = { 1, 1 }; 2 MyPoint endPoint = { 8, 8 };
第八步准备一个容器 来保存可通行路径
CMyStack<MyPoint> ms;
ms.push(beginPoint);//把起点压入到容器中,用来查找后续的结点
第九步准备一个辅助坐标点 帮助来判断下一个可通行位置
1 MyPoint NearPoint = beginPoint;//辅助点先为起点,然后通过起点设定的方向来对周边路径进行搜索
第十步开始寻路
1 while (true)//无法确定循环次数
2 {
3 switch (pathArr[NearPoint.row][NearPoint.col].dir)//判断当前起点在辅助数组中设定的方向
4 {
5 case p_up:
6 //if (pathArr[NearPoint.row - 1][NearPoint.col].val == 0 && //表示当前点的上一行位置是可通行的
7 // pathArr[NearPoint.row - 1][NearPoint.col].isFind == false)//表示当前点的上一行位置是没有访问的
8 pathArr[NearPoint.row][NearPoint.col].dir = p_left;//当前路口的下一个方向标记出来
9 if (IsMove(pathArr, NearPoint.row - 1, NearPoint.col))
10 {
11 //表示当前坐标的上方向能通行
12 pathArr[NearPoint.row][NearPoint.col].isFind = true;//当前点改为已访问
13 MyPoint temp = { NearPoint.row - 1, NearPoint.col };
14 ms.push(temp);//压入这个坐标
15 NearPoint = temp;//把这个上方向可通行的点赋值给辅助点,进行下一次的搜索
16 }
17 break;
18 case p_left:
19 pathArr[NearPoint.row][NearPoint.col].dir = p_down;//当前路口的下一个方向标记出来
20 if (IsMove(pathArr, NearPoint.row, NearPoint.col - 1))
21 {
22 //表示当前坐标的上方向能通行
23 pathArr[NearPoint.row][NearPoint.col].isFind = true;//当前点改为已访问
24 MyPoint temp = { NearPoint.row, NearPoint.col - 1 };
25 ms.push(temp);//压入这个坐标
26 NearPoint = temp;//把这个上方向可通行的点赋值给辅助点,进行下一次的搜索
27 }
28 break;
29 case p_down:
30 pathArr[NearPoint.row][NearPoint.col].dir = p_right;//当前路口的下一个方向标记出来
31 if (IsMove(pathArr, NearPoint.row + 1, NearPoint.col))
32 {
33 //表示当前坐标的上方向能通行
34 pathArr[NearPoint.row][NearPoint.col].isFind = true;//当前点改为已访问
35 MyPoint temp = { NearPoint.row + 1, NearPoint.col };
36 ms.push(temp);//压入这个坐标
37 NearPoint = temp;//把这个上方向可通行的点赋值给辅助点,进行下一次的搜索
38 }
39 break;
40 case p_right://最后一个方向,表示前面三个方向已经搜索完成
41 if (IsMove(pathArr, NearPoint.row, NearPoint.col + 1))
42 {
43 //表示当前坐标的上方向能通行
44 pathArr[NearPoint.row][NearPoint.col].isFind = true;//当前点改为已访问
45 MyPoint temp = { NearPoint.row, NearPoint.col + 1};
46 ms.push(temp);//压入这个坐标
47 NearPoint = temp;//把这个上方向可通行的点赋值给辅助点,进行下一次的搜索
48 }
49 else
50 {
51 //表示当前路口所有方向都不通,要准备退栈
52 MyPoint tempPoint = ms.getTop();//得到退栈之前的栈顶元素
53 pathArr[tempPoint.row][tempPoint.col].isFind = true;//要退出栈的这个元素也是已经访问过了
54 ms.pop();
55 if (!ms.empty())//如果栈不为空
56 NearPoint = ms.getTop();//得到新的栈顶元素
57 }
58 break;
59 }
60
61 if (NearPoint.row == endPoint.row && NearPoint.col == endPoint.col)
62 break;//找到终点
63 if (ms.empty())
64 break;//没有终点
65 }
66
67 while (!ms.empty())
68 {
69 MyPoint tempPoint = ms.getTop();
70 printf("row = %d, col = %d\n",tempPoint.row,tempPoint.col);
71 ms.pop();
72 }
总体代码

1 #pragma one
2 template<typename T>
3 class CMyStack
4 {
5 T *pBuff;
6 size_t len;
7 size_t maxSize;
8 public:
9 CMyStack();
10 ~CMyStack();
11 void clear();
12 public:
13 void push(T const& elem);
14 void pop();
15 T const& getTop() const{ return pBuff[len - 1]; }
16 bool empty() const{ return len == 0; }
17 };
18
19 template<typename T>
20 void CMyStack<T>::pop()
21 {
22 --len;
23 }
24
25 template<typename T>
26 void CMyStack<T>::push(T const& elem)
27 {
28 if (len>=maxSize)
29 {
30 maxSize = maxSize + ((maxSize >> 1) > 1 ? (maxSize >> 1) : 1);
31 T *tempBuff = new T[maxSize];
32 for (size_t i = 0; i < len; i++)
33 tempBuff[i] = pBuff[i];
34 if (pBuff != nullptr)
35 delete[] pBuff;
36 pBuff = tempBuff;
37 }
38 pBuff[len++] = elem;
39 }
40
41 template<typename T>
42 void CMyStack<T>::clear()
43 {
44 if (pBuff!=nullptr)
45 {
46 delete[] pBuff;
47 pBuff = nullptr;
48 len = maxSize = 0;
49 }
50 }
51
52
53 template<typename T>
54 CMyStack<T>::~CMyStack()
55 {
56 clear();
57 }
58
59 template<typename T>
60 CMyStack<T>::CMyStack()
61 {
62 pBuff = nullptr;
63 len = maxSize = 0;
64 }

1 //深度优先搜索.cpp : 定义控制台应用程序的入口点。
2 //
3
4 #include "stdafx.h"
5 #include "MyStack.h"
6
7 //深度优先搜索
8
9 //作业:1、在示例中方向顺序为上,左,下,右,如果更换这个方向顺序会有什么影响?
10 // 2、深度寻路在有路的情况下,不一定能找到路,为什么?
11
12 //规则:沿一个方向进行行走,到了岔路口又一次选择一个方向进行前进,如果碰到死胡同退回到上一个岔路口重新选择方向
13 // 走过的路不会再走,一次走一个节点
14
15 //1、准备地图 (二维数组,用1表示是障碍,不可通行,用0表示可以通行)
16 #define MAP_ROW 10
17 #define MAP_COL 10
18
19 //2、准备方向
20 enum Path_Dir{ p_up, p_down,p_left,p_right };
21
22 //3、准备一个栈,用来保存搜索过程中可以行走的路径点信息(在规划中有后进的先出)
23
24 //4、准备一个结构,用来保存每一个路径点在二维数组的行列值
25 struct MyPoint
26 {
27 int row, col;
28 };
29
30 //5、准备一个辅助数组(1、资源地图数组不能变;2、对资源地图要进数据标记)
31 struct PathNode
32 {
33 int val;//保存原始资源的路径点信息
34 Path_Dir dir;//当前路径点的方向标记
35 bool isFind;//当前路径点是否被访问过
36 };
37
38 //准备一个函数,用来判断参数的坐标是否可以通行
39 bool IsMove(PathNode p[][MAP_COL],int row,int col)
40 {
41 if (row < 0 || row >= MAP_ROW || col < 0 || col >= MAP_COL)
42 return false;//如果越界,不需要进行位置的判断
43 if (p[row][col].val != 0 || p[row][col].isFind == true)
44 return false;//表示当前行列的元素要么是障碍,要么已经被访问过,不能通行
45 return true;
46 }
47
48
49 int _tmain(int argc, _TCHAR* argv[])
50 {
51 int mapArr[MAP_ROW][MAP_COL] = {
52 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
53 { 1, 0, 0, 1, 1, 0, 0, 0, 1, 1 },
54 { 1, 1, 0, 1, 1, 0, 1, 0, 1, 1 },
55 { 1, 1, 0, 0, 0, 0, 1, 0, 1, 1 },
56 { 1, 1, 0, 1, 1, 0, 1, 0, 1, 1 },
57 { 1, 1, 0, 1, 1, 0, 1, 0, 1, 1 },
58 { 1, 1, 0, 1, 1, 0, 1, 0, 1, 1 },
59 { 1, 1, 0, 1, 1, 0, 1, 0, 1, 1 },
60 { 1, 0, 0, 1, 0, 0, 1, 0, 0, 1 },
61 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
62 };
63
64 //第6步
65 PathNode pathArr[MAP_ROW][MAP_COL];
66 for (int i = 0; i < MAP_ROW; ++i)
67 {
68 for (int j = 0; j < MAP_COL; ++j)
69 {
70 pathArr[i][j].val = mapArr[i][j];
71 pathArr[i][j].isFind = false;//表示地图中的每一个节点都没有被访问过
72 pathArr[i][j].dir = p_up;//表示给地图中的每一个节点都设定一个初始方向
73 }
74 }
75
76 //第7步
77 MyPoint beginPoint = { 1, 1 };
78 MyPoint endPoint = { 8, 8 };
79
80 //第8步:准备一个容器,用来保存可通行路径点
81 CMyStack<MyPoint> ms;
82 ms.push(beginPoint);//把起点压入到容器中,用来查找后续的结点
83
84 //第9步:准备一个辅助坐标点,帮助来判断下一个可通行位置
85 MyPoint NearPoint = beginPoint;//辅助点先为起点,然后通过起点设定的方向来对周边路径进行搜索
86
87 //第10步:开始寻路
88 while (true)//无法确定循环次数
89 {
90 switch (pathArr[NearPoint.row][NearPoint.col].dir)//判断当前起点在辅助数组中设定的方向
91 {
92 case p_up:
93 //if (pathArr[NearPoint.row - 1][NearPoint.col].val == 0 && //表示当前点的上一行位置是可通行的
94 // pathArr[NearPoint.row - 1][NearPoint.col].isFind == false)//表示当前点的上一行位置是没有访问的
95 pathArr[NearPoint.row][NearPoint.col].dir = p_left;//当前路口的下一个方向标记出来
96 if (IsMove(pathArr, NearPoint.row - 1, NearPoint.col))
97 {
98 //表示当前坐标的上方向能通行
99 pathArr[NearPoint.row][NearPoint.col].isFind = true;//当前点改为已访问
100 MyPoint temp = { NearPoint.row - 1, NearPoint.col };
101 ms.push(temp);//压入这个坐标
102 NearPoint = temp;//把这个上方向可通行的点赋值给辅助点,进行下一次的搜索
103 }
104 break;
105 case p_left:
106 pathArr[NearPoint.row][NearPoint.col].dir = p_down;//当前路口的下一个方向标记出来
107 if (IsMove(pathArr, NearPoint.row, NearPoint.col - 1))
108 {
109 //表示当前坐标的上方向能通行
110 pathArr[NearPoint.row][NearPoint.col].isFind = true;//当前点改为已访问
111 MyPoint temp = { NearPoint.row, NearPoint.col - 1 };
112 ms.push(temp);//压入这个坐标
113 NearPoint = temp;//把这个上方向可通行的点赋值给辅助点,进行下一次的搜索
114 }
115 break;
116 case p_down:
117 pathArr[NearPoint.row][NearPoint.col].dir = p_right;//当前路口的下一个方向标记出来
118 if (IsMove(pathArr, NearPoint.row + 1, NearPoint.col))
119 {
120 //表示当前坐标的上方向能通行
121 pathArr[NearPoint.row][NearPoint.col].isFind = true;//当前点改为已访问
122 MyPoint temp = { NearPoint.row + 1, NearPoint.col };
123 ms.push(temp);//压入这个坐标
124 NearPoint = temp;//把这个上方向可通行的点赋值给辅助点,进行下一次的搜索
125 }
126 break;
127 case p_right://最后一个方向,表示前面三个方向已经搜索完成
128 if (IsMove(pathArr, NearPoint.row, NearPoint.col + 1))
129 {
130 //表示当前坐标的上方向能通行
131 pathArr[NearPoint.row][NearPoint.col].isFind = true;//当前点改为已访问
132 MyPoint temp = { NearPoint.row, NearPoint.col + 1 };
133 ms.push(temp);//压入这个坐标
134 NearPoint = temp;//把这个上方向可通行的点赋值给辅助点,进行下一次的搜索
135 }
136 else
137 {
138 //表示当前路口所有方向都不通,要准备退栈
139 MyPoint tempPoint = ms.getTop();//得到退栈之前的栈顶元素
140 pathArr[tempPoint.row][tempPoint.col].isFind = true;//要退出栈的这个元素也是已经访问过了
141 ms.pop();
142 if (!ms.empty())//如果栈不为空
143 NearPoint = ms.getTop();//得到新的栈顶元素
144 }
145 break;
146 }
147
148 if (NearPoint.row == endPoint.row && NearPoint.col == endPoint.col)
149 break;//找到终点
150 if (ms.empty())
151 break;//没有终点
152 }
153
154 while (!ms.empty())
155 {
156 MyPoint tempPoint = ms.getTop();
157 printf("row = %d, col = %d\n", tempPoint.row, tempPoint.col);
158 ms.pop();
159 }
160 return 0;
161 }
