栈与队列的应用——深度、广度优先搜索迷宫出口

今天,寒假第2天。

今天看的是栈与队列。课本上关于栈,列举了一些应用实例。其中一个就是关于迷宫出口的搜索问题。想起之前在刘汝佳的《算法竞赛入门经典》上的关于这个问题的深度优先方法。通过深度优先方法,可以求出最短的走出迷宫的路径,其基本思想是:将整个迷宫地图视为一棵二叉树,其中在迷宫中先走到的地方视为它所能及地方的双亲节点,于是:迷宫的起始点可视为根节点,与迷宫一步之遥的所有节点都可视为根节点的孩子节点,与孩子节点一步之遥的又可视为孩子的孩子节点...依此类推。当然,我们还需要一个数组记录已经走过的节点,这些节点是不需再走第二次的,如果经过这些节点能到达终点,走一次就够了,何况先前“抢占”该节点的路径一定能更先到达终点。

如果利用栈的方式,则是“一条路走到黑”,要么走到了终点,要么走到死胡同再折返回来。这种方式同样需要记录已走过的节点,以免浪费不必要的时间。

这两种方法实现起来都不太难,基本思路就是BFS(广度优先)和DFS(深度优先)的基本思路。关于最后输出的问题,如果用DFS,只需用一个数组,走一步标记一下,返一步在标记回来,这样最后就能得到结果了;如果用BFS会稍微复杂一些,因为这种方式是“齐头并进”,大家一起一步一步往前走,很难做标记。因此在走的过程中,要用一个数组,能体现出后面经过的节点与它之前节点之间的关系,一种具体方法是:在arr[x][y]中存放走到坐标(x,y)的前一步的坐标。这样顺着出口往回找,最终一定能找到入口。

运行结果如下:(图一)基于栈的DFS,(图二)基于队列的BFS。两者结果不同,其中BFS的是最短路径。

图一 DFS  图二 BFS

View Code
  1 /*
  2     功能:
  3         使用栈,实现对于迷宫的广度优先搜索。
  4     输入:
  5   6     输出:
  7         迷宫图形
  8     FINISHED DATE:
  9         2013.1.13 
 10 */
 11 #include <stdio.h>
 12 #include <stdlib.h>
 13 #include <string.h>
 14 //define size value
 15 #define MAXWIDTH 5
 16 #define MAXLENGTH 8
 17 #define STACKSIZE 100
 18 //define return value
 19 #define ERROR 0
 20 #define OK 1
 21 #define OVERFLOW 0
 22 typedef struct {
 23     int x,y;
 24 }Pos;
 25 typedef struct {
 26     Pos *base,*top;
 27     int stack_size;
 28 }Stack;
 29 bool StackEmpty(Stack s) {
 30     return (s.top == s.base);
 31 }
 32 int StackPop(Stack &s,Pos &p,bool isPop)
 33 {
 34     if(s.base == s.top)
 35         return ERROR;
 36     p.x = (s.top-1)->x;
 37     p.y = (s.top-1)->y;
 38     if(isPop) s.top--;
 39     return OK;
 40 }
 41 int StackPush(Stack &s,Pos p)
 42 {
 43     if(s.top-s.base >= s.stack_size)
 44         return ERROR;    
 45     s.top->x = p.x;
 46     s.top->y = p.y;
 47     s.top++;
 48     return OK;
 49 }
 50 int InitStack(Stack &s)
 51 {
 52     s.base = s.top = (Pos *)malloc(sizeof(Pos)*STACKSIZE);
 53     if(!s.base) return OVERFLOW;
 54     s.stack_size = STACKSIZE;
 55     return OK;
 56 }
 57 void FindPath(int Maze[MAXWIDTH][MAXLENGTH],Pos des)
 58 {
 59     Stack s;Pos pos;    
 60     int footprint[MAXWIDTH][MAXLENGTH]={0},res[MAXWIDTH][MAXLENGTH]={0};
 61     InitStack(s);    
 62     pos.x = pos.y = 0;//起始点为(0,0)
 63     StackPush(s,pos);
 64     footprint[0][0] = res[0][0] = 1;
 65     while(!StackEmpty(s)) {
 66         StackPop(s,pos,false);
 67         if(pos.x == des.x && pos.y == des.y)
 68             break;
 69         if(pos.y+1 < MAXLENGTH && !footprint[pos.x][pos.y+1] && !Maze[pos.x][pos.y+1]) {
 70             footprint[pos.x][pos.y+1] = res[pos.x][pos.y+1] = 1;
 71             pos.y++;
 72             StackPush(s,pos);
 73         }
 74         else if(pos.x+1 < MAXWIDTH && !footprint[pos.x+1][pos.y] && !Maze[pos.x+1][pos.y]) {
 75             footprint[pos.x+1][pos.y] =res[pos.x+1][pos.y] = 1;
 76             pos.x++;
 77             StackPush(s,pos);
 78         }
 79         else if(pos.y-1 >= 0 && !footprint[pos.x][pos.y-1] && !Maze[pos.x][pos.y-1]) {
 80             footprint[pos.x][pos.y-1] = res[pos.x][pos.y-1] = 1;
 81             pos.y--;
 82             StackPush(s,pos);
 83         }
 84         else if(pos.x-1 >= 0 && !footprint[pos.x-1][pos.y] && !Maze[pos.x-1][pos.y]) {
 85             footprint[pos.x-1][pos.y] = res[pos.x-1][pos.y] = 1;
 86             pos.x--;
 87             StackPush(s,pos);
 88         }
 89         else {
 90             StackPop(s,pos,true);
 91             res[pos.x][pos.y] = 0;
 92         }
 93     }
 94     if(!StackEmpty(s)) {    
 95     //have found the path
 96         printf("  ");
 97         for(int j = 0;j<MAXLENGTH;++j) 
 98             printf("%d ",j);
 99         printf("\n");
100         for(int i = 0;i<MAXWIDTH;++i) {
101             printf("%d ",i);
102             for(int j = 0;j<MAXLENGTH;++j) {
103                 if(res[i][j]) {
104                     printf("");
105                 }
106                 else if(Maze[i][j]) printf("");
107                 else printf("  ");
108             }
109             printf("\n");
110         }
111     }
112     else printf("No path found!\n");
113 }
114 int main()
115 {
116     int Maze[MAXWIDTH][MAXLENGTH] = {{0,0,0,0,1,1,1,0},{0,1,0,1,0,0,0,0},{0,1,0,0,0,1,1,0},{0,0,0,1,1,1,0,0},{1,1,0,0,0,0,0,0}};
117     Pos des;
118     des.x = 4;des.y = 7;
119     FindPath(Maze,des);
120     system("pause");
121     return 0; 
122 }

 

View Code
  1 /*
  2     功能:
  3         使用队列,实现对于迷宫的深度优先搜索。找到最短路径。 
  4     输入:
  5   6     输出:
  7         迷宫图形
  8     FINISHED DATE:
  9         2013.1.13 
 10 */
 11 #include <stdio.h>
 12 #include <stdlib.h>
 13 #include <string.h>
 14 //define size value
 15 #define MAXWIDTH 5
 16 #define MAXLENGTH 8
 17 #define MAXSIZE 5000
 18 //define return value
 19 #define ERROR 0
 20 #define OK 1
 21 #define OVERFLOW 0
 22 typedef struct {
 23     int x,y;
 24 }Pos;
 25 typedef struct {
 26     Pos *base;
 27     int front,rear;
 28     int queue_size;
 29 }Queue; 
 30 int InitQueue(Queue &q)
 31 {
 32     q.base = (Pos*)malloc(sizeof(Pos)*MAXSIZE);
 33     q.front = q.rear = 0;
 34     q.queue_size = MAXSIZE;
 35     return OK;
 36 }
 37 int QueuePush(Queue &q,Pos pos)
 38 {
 39     //Queue is full
 40     if((q.rear+1)%q.queue_size==q.front) {
 41         return ERROR;
 42     }
 43     q.base[q.rear].x = pos.x;
 44     q.base[q.rear].y = pos.y;
 45     q.rear = (q.rear+1)%q.queue_size;
 46     return OK;
 47 }
 48 int QueuePop(Queue &q,Pos &pos,bool isPop)
 49 {
 50     //queue is empty
 51     if(q.front==q.rear) {
 52         return ERROR;
 53     }
 54     pos.x = q.base[q.front].x;
 55     pos.y = q.base[q.front].y;
 56     if(isPop) q.front = (q.front+1)%q.queue_size;
 57     return OK;
 58 }
 59 bool QueueEmpty(Queue q)
 60 {
 61     return (q.rear==q.front);
 62 }
 63 void FindPath(int Maze[MAXWIDTH][MAXLENGTH],Pos des)
 64 {
 65     Queue q;Pos pos,tmp;
 66     int footprint[MAXWIDTH][MAXLENGTH]={0};
 67     Pos res[MAXWIDTH][MAXLENGTH];
 68     InitQueue(q);
 69     pos.x = 0;pos.y = 0;
 70     QueuePush(q,pos);
 71     while(!QueueEmpty(q)){
 72         QueuePop(q,pos,1);
 73         if(pos.x == des.x && pos.y == des.y)
 74             break;
 75         if(pos.y+1 < MAXLENGTH && !footprint[pos.x][pos.y+1] && !Maze[pos.x][pos.y+1]) {
 76             footprint[pos.x][pos.y+1] = 1;
 77             res[pos.x][pos.y+1].x = pos.x;
 78             res[pos.x][pos.y+1].y = pos.y;
 79             tmp.x = pos.x;
 80             tmp.y = pos.y+1;
 81             QueuePush(q,tmp);
 82         }
 83         if(pos.x+1 < MAXWIDTH && !footprint[pos.x+1][pos.y] && !Maze[pos.x+1][pos.y]) {
 84             footprint[pos.x+1][pos.y] = 1;
 85             res[pos.x+1][pos.y].x = pos.x;
 86             res[pos.x+1][pos.y].y = pos.y;
 87             tmp.x = pos.x+1;
 88             tmp.y = pos.y;
 89             QueuePush(q,tmp);
 90         }
 91         if(pos.y-1 >= 0 && !footprint[pos.x][pos.y-1] && !Maze[pos.x][pos.y-1]) {
 92             footprint[pos.x][pos.y-1] = 1;
 93             res[pos.x][pos.y-1].x = pos.x;
 94             res[pos.x][pos.y-1].y = pos.y;
 95             tmp.x = pos.x;
 96             tmp.y = pos.y-1;
 97             QueuePush(q,tmp);
 98         }
 99         if(pos.x-1 >= 0 && !footprint[pos.x-1][pos.y] && !Maze[pos.x-1][pos.y]) {
100             footprint[pos.x-1][pos.y] = 1;
101             res[pos.x-1][pos.y].x = pos.x;
102             res[pos.x-1][pos.y].y = pos.y;
103             tmp.x = pos.x-1;
104             tmp.y = pos.y;
105             QueuePush(q,tmp);
106         }
107     }
108     if(!QueueEmpty(q)) {
109     //have found the path    
110         int x,y,tx;
111         x = des.x;
112         y = des.y;
113         memset(footprint,0,MAXWIDTH*MAXLENGTH*sizeof(int));
114         while(x!=0||y!=0) {    
115             footprint[x][y] = 1;
116             tx = res[x][y].x;
117             y = res[x][y].y;
118             x = tx;
119         }
120         footprint[x][y] = 1;
121         printf("  ");
122         for(int j = 0;j<MAXLENGTH;++j) 
123             printf("%d ",j);
124         printf("\n");
125         for(int i = 0;i<MAXWIDTH;++i) {
126             printf("%d ",i);
127             for(int j = 0;j<MAXLENGTH;++j) {
128                 if(footprint[i][j]) {
129                     printf("");
130                 }
131                 else if(Maze[i][j]) printf("");
132                 else printf("  ");
133             }
134             printf("\n");
135         }
136     }
137     else printf("No path found!\n");
138     
139 }
140 int main()
141 {
142     int Maze[MAXWIDTH][MAXLENGTH] = {{0,0,0,0,1,1,1,0},{0,1,0,1,0,0,0,0},{0,1,0,0,0,1,1,0},{0,0,0,1,1,1,0,0},{1,1,0,0,0,0,0,0}};
143     Pos des;
144     des.x = 4;des.y = 7;
145     FindPath(Maze,des);
146     system("pause");
147     return 0; 
148 }

 

 

转载于:https://www.cnblogs.com/epsilon/archive/2013/01/13/2858944.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值