深度优先搜索
深度优先遍历的思想:从一个顶点V0开始,沿着一条路一直走到底,如果发现不能到达目标解,那就返回到上一个节点,然后从另一条路开始走到底,这种尽量往深处走的概念即是深度优先的概念。
深度优先搜索可以用栈来实现,在栈中保存从起始结点,到当前结点路径上的所有结点,一般运用递归实现, 递归的基本思想:某个函数直接或间接地调用自身。递归的关键问题:1.找出递归公式。2、找出递归终止条件。
例题:走迷宫问题(深度优先搜索实现)
给定一个二维数组 int map[5][5] = {
0 , 1 , 0 , 0 , 0 ,
0 , 1 , 0 , 1 , 0 ,
0 , 0 , 0 , 0 , 0 ,
0 , 1 , 1 , 1 , 0 ,
0 , 0 , 0 , 1 , 0 ,
} ;
它表示一个迷宫,其中“1”表示墙壁,“0”表示可以走的路,只能横着走或者竖着走,不能斜着走,要求编写程序求出从左上角到右下角的最短路径的长度,例如上述问题输出结果为:8
四个方向,每次选择一个方向走,不通时走下一个方向,如果四个方向都不能走时,则退一格。
#include
#include
using namespace std ;
struct dot {
int step ;
}d[100][100];
int m , n ;
bool is_ok(int x , int y) {
if(x < 0 || x >= m || y < 0 || y >= n)
return 0 ;
return 1 ;
}
int dx[] = {0 , -1 , 0 , 1} ;
int dy[] = {1 , 0 , -1 , 0} ;
int vis[100][100] = {0} , map[100][100] ;
bool flag = 0 ;
void dfs(int x , int y) {
if(x == 4 && y == 4) {
cout << d[x][y].step << endl ;
flag = 1 ;
return ;
}
for(int i = 0 ; i < 4 ; i++) {
int xx , yy ;
xx = x + dx[i] ;
yy = y + dy[i] ;
if(!vis[xx][yy]&&map[xx][yy] != 1 &&is_ok(xx,yy)) {
vis[xx][yy] = 1 ;
d[xx][yy].step = d[x][y].step + 1 ;
dfs(xx,yy) ;
if(flag)
return ;
vis[xx][yy] = 0 ;
}
}
}
int main() {
cin >> m >> n ;
for(int i = 0 ; i < m ; i++)
for(int j = 0 ; j < n ; j++)
cin >> map[i][j] ;
d[0][0].step = 0 ;
dfs(0,0);
return 0 ;
}
如果想输出所走路径,可以使用以下方法:
#include
#include
#include
using namespace std ;
struct dot {
int x , y ;
int step ;
}d[100][100];
int m , n ;
bool is_ok(int x , int y) {
if(x < 0 || x >= m || y < 0 || y >= n)
return 0 ;
return 1 ;
}
int dx[] = {0 , -1 , 0 , 1} ;
int dy[] = {1 , 0 , -1 , 0} ;
int vis[100][100] = {0} , map[100][100] ;
bool flag = 0 ;
void dfs(int x , int y) {
if(x == 4 && y == 4) {
cout << d[x][y].step << endl ;
flag = 1 ;
return ;
}
for(int i = 0 ; i < 4 ; i++) {
int xx , yy ;
xx = x + dx[i] ;
yy = y + dy[i] ;
if(!vis[xx][yy]&&map[xx][yy] != 1 &&is_ok(xx,yy)) {
vis[xx][yy] = 1 ;
d[xx][yy].x = x ;
d[xx][yy].y = y ;
d[xx][yy].step = d[x][y].step + 1 ;
dfs(xx,yy) ;
if(flag)
return ;
d[xx][yy].x = -1 ;
d[xx][yy].y = -1 ;
vis[xx][yy] = 0 ;
}
}
}
int main() {
cin >> m >> n ;
for(int i = 0 ; i < m ; i++)
for(int j = 0 ; j < n ; j++)
cin >> map[i][j] ;
memset(d,-1,sizeof(d)) ;
d[0][0].step = 0 ;
dfs(0,0);
for(int i = 0 ; i < m ; i++)
for(int j = 0 ; j < n ; j++)
if(d[i][j].x != -1)
cout << "(" << d[i][j].x << " , " << d[i][j].y << ")" << endl ;
cout << "(4 , 4)" << endl ;
return 0 ;
}
同样可以使用栈来实现深度优先搜索:
#include
#include
#include
#include
using namespace std ;
struct dot {
int x , y ;
int step ;
};
int m , n ;
stack s ;
bool is_ok(int x , int y) {
if(x < 0 || x >= m || y < 0 || y >= n)
return 0 ;
return 1 ;
}
int dx[] = {1 , 0 , -1 , 0} ;
int dy[] = {0 , -1 , 0 , 1} ;
int vis[100][100] = {0} , map[100][100] ;
void dfs() {
while(!s.empty()) {
dot cur = s.top() ;
s.pop() ;
if(cur.x == 4 && cur.y == 4) {
cout << cur.step << endl ;
return ;
}
for(int i = 0 ; i < 4 ; i++) {
dot next ;
next.x = cur.x + dx[i] ;
next.y = cur.y + dy[i] ;
if(!vis[next.x][next.y]&&map[next.x][next.y] != 1 &&is_ok(next.x,next.y)) {
vis[next.x][next.y] = 1 ;
next.step = cur.step + 1 ;
s.push(next) ;
}
}
}
return ;
}
int main() {
cin >> m >> n ;
for(int i = 0 ; i < m ; i++)
for(int j = 0 ; j < n ; j++)
cin >> map[i][j] ;
dot cur ;
cur.x = 0 ;
cur.y = 0 ;
cur.step = 0 ;
s.push(cur) ;
dfs();
return 0 ;
}