码迷,mamicode.com
首页 > 编程语言 > 详细

简单迷宫算法(递归与非递归C++实现)

时间:2017-01-19 04:37:55      阅读:516      评论:0      收藏:0      [点我收藏+]

标签:path   ++   space   ges   ack   非递归   技术分享   ret   pat   

假定迷宫如下:1代表墙,0代表道路,起点在(1,1),终点(11,9)(PS:下标从0开始计算)。

技术分享

现在寻求一条路径能从起点到达终点(非最短)。

有两种解法:递归与非递归。

递归算法思路:

  要用递归,就要寻找一个子问题,该子问题是递归的。很明显,这道题的子问题就是从8个方向(上下左右还有四个斜角)中寻找一个可行方向并向前走一步,该子问题(seekPath函数)的实现代码如下:

  

 1 struct offset{ 
 2     int x;
 3     int y;
 4 };
 5 offset move[8]={{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1}};//8个不同行动方向下的x和y偏移量 
 6 int mark[12][12]={0};//将数组所有节点访问位置0(未访问) 
 7 char a[][13]={    "111111111111",
 8                   "101101101111",                    
 9                   "110010011111",
10                   "110111111111",
11                   "111001111111",
12                   "111110001111",
13                   "111010110111",
14                   "110101111011",
15                   "110111111111",
16                   "110100001111",
17                   "110011100111",
18                   "111111111011"    
19                 };//迷宫数组 
20 list<offset> s;//存放成功路径 
21 
22 int seekPath(int x,int y){//行动一步 
23     int next_x,next_y;
24     if(x==11&&y==9) return 1;//找到出口 
25     for(int i=0;i<8;i++){//朝8个方向试探下一步 
26         next_x=move[i].x+x;
27         next_y=move[i].y+y;
28         if(mark[next_x][next_y]==0&&a[next_x][next_y]==0){//下一步未走过并且是道路 
29             mark[next_x][next_y]=1;//标记该点已经走过
30             if(seekPath(next_x,next_y)){
31                 offset a={next_x,next_y};
32                 s.push_front(a); //记录正确路径   
33                 return 1;
34             }
35         }
36     }
37     if(x==1&&y==1){//死迷宫 
38         cout<<"failed"<<endl;
39     }
40         return 0;    
41 }

  递归过程中,在每个点上有8个方向,在某个方向上若能满足“该方向点未走过并且是道路 ”的条件,即可执行下一步(下一步的方向从第一个方向重新开始计算),直到找到递归出口。递归出口自然是行走到终点的情况。

  测试代码如下:

  

 1 int main(){//测试代码 
 2     mark[1][1]=1;
 3     if(seekPath(1,1))
 4         s.push_front(offset{1,1});
 5     list<offset>::iterator it=s.begin();
 6     while(it!=s.end()){
 7         cout<<"("<<it->x<<","<<it->y<<")";
 8         it++;
 9     }
10     return 0;
11 }

非递归算法思路:

  我们首先需要一个辅助链表,链表的作用是为了记录正确路径。从起点开始,有8个方向,若能满足“该方向点未走过并且是道路 ”的条件,即可将该点放入表尾并执行下一步(下一步的方向从第一个方向重新开始计算),当8个方向都不能满足条件时,将该点从表尾删除并回退到上一个点。实现代码如下:

  

 1 #include <iostream>
 2 #include <list> 
 3 using namespace std;
 4 struct offset{ 
 5     int x;
 6     int y;
 7 };
 8 struct point{ 
 9     int x;
10     int y;
11 };
12 offset move[8]={{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1}};//8个不同行动方向下的x和y偏移量 
13 int mark[12][12]={0};//将数组所有节点访问位置0(未访问) 
14 char a[][13]={    "111111111111",
15                   "101101101111",                    
16                   "110010011111",
17                   "110111111111",
18                   "111001111111",
19                   "111110001111",
20                   "111010110111",
21                   "110101111011",
22                   "110111111111",
23                   "110100001111",
24                   "110011100111",
25                   "111111111011"        
26                 };//迷宫数组 
27 
28 int main(){//测试代码 
29     mark[1][1]=1;
30     list<point> lists;//存放路径 
31     point s={1,1};
32     lists.push_back(s);
33     while(!lists.empty()){
34         s=lists.back();
35         for(int d=0;d<8;d++){//朝8个方向试探下一步 
36             int x=s.x+move[d].x;
37             int y=s.y+move[d].y;
38             if(x==11&&y==9){//找到出口 
39                 s.x=x;
40                 s.y=y;
41                 lists.push_back(s);
42                 goto end;  
43             }
44             if(a[x][y]==0&&mark[x][y]==0){//下一步未走过并且是道路 
45                 mark[x][y]=1;
46                 point temp={x,y};
47                 lists.push_back(temp);
48                 s.x=x;
49                 s.y=y;
50                 d=0;
51             }
52         }
53             lists.pop_back();//删除不可达路径 
54     }
55     cout<<"failed";
56     end:list<point>::iterator it=lists.begin();
57     while(it!=lists.end()){
58         cout<<"("<<it->x<<","<<it->y<<")";
59         it++;
60     }
61     return 0;
62 }

 

 

    

简单迷宫算法(递归与非递归C++实现)

标签:path   ++   space   ges   ack   非递归   技术分享   ret   pat   

原文地址:http://www.cnblogs.com/ytz1996/p/6298676.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!