1 问题
定义一个二维数组:
int maze[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表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的路线。[Linux C编程一站式学习 12.3题目,没读懂题目要求是找到所有的路线还是一条路线]。
2 用堆栈来实现深度优先过程
在迷宫中可以走的路(数组maze中值为0的元素的坐标)用堆栈数据结构保存[在迷宫中(数组中当前坐标为0的元素的坐标)先探索是否可以往右、下、左、上的顺序走,如果可以就将这些右边的、下边的、左边的、上面的元素的坐标记录下来]。然后再将栈顶的元素坐标取出来(上,左,下,右)按照相同的方式探索此元素周围的其它元素,当出现走不通情况时,由于堆栈的每次出栈操作,堆栈的下一次出栈操作就会使得另外一个方向的元素坐标被压出来。对于左和右来说,在迷宫中往上和下走总是优先,故而有深度优先的特点。
3 C代码
平台:debain GNU/Linux 3.2.04
代码中将maze[4][3]由原来的1改为0,以验证程序向左和向上搜索通道。从左下角到右下角所有的通路代码:
-
-
-
-
-
-
- #include
-
-
-
-
- #define ROAD 0
- #define AREADY_WALK 2
- #define ROW 5
- #define COL 5
- #define N ROW * COL
-
-
-
-
-
- static int maze[ROW][COL] = {
- {0, 1, 0, 0, 0},
- {0, 1, 0, 1, 0},
- {0, 0, 0, 0, 0},
- {0, 1, 1, 1, 0},
- {0, 0, 0, 0, 0}
- };
-
-
- static int top;
- static struct point {
- int row;
- int col;
- }p, stack[N];
-
-
-
-
-
- void go_maze(void);
- void maze_visit(int row, int col, struct point p);
- void print_maze(void);
- void stack_push(struct point p);
- struct point stack_pop(void);
- int stack_empty(void);
-
-
-
-
- int main(void)
- {
- go_maze();
-
- return 0;
- }
-
-
-
-
-
-
-
- void print_maze(void)
- {
- int i, j;
- for(i = 0; i < ROW; ++i){
- for(j = 0; j < COL; ++j)
- printf("%d\t", maze[i][j]);
- printf("\n");
- }
- printf("----------------------------------\n");
- }
-
-
-
-
-
- void go_maze(void)
- {
-
- p.row = p.col = 0;
- maze[p.row][p.col] = AREADY_WALK;
- stack_push(p);
-
-
- while(!stack_empty()){
-
- p = stack_pop();
-
-
-
-
-
- if(p.col < COL - 1 && ROAD == maze[p.row][p.col + 1]){
- maze_visit(p.row, p.col + 1, p);
- }
-
-
- if(p.row < ROW - 1 && ROAD == maze[p.row + 1][p.col]){
- maze_visit(p.row + 1, p.col, p);
- }
-
-
- if(p.col > 0 && ROAD == maze[p.row][p.col - 1]){
- maze_visit(p.row, p.col - 1, p);
- }
-
-
- if(p.row > 0 && ROAD == maze[p.row - 1][p.col]){
- maze_visit(p.row - 1, p.col, p);
- }
-
-
- print_maze();
- }
- }
-
-
-
-
-
- void maze_visit(int row, int col, struct point p)
- {
- struct point around_p = {row, col};
- maze[row][col] = AREADY_WALK;
- stack_push(around_p);
- }
-
-
-
-
-
- void stack_push(struct point p)
- {
- if(top < N){
- stack[top++] = p;
- }
- }
-
-
-
-
-
- struct point stack_pop(void)
- {
- if(!stack_empty()){
- return stack[--top];
- }else{
- struct point p = {-1, -1};
- return p;
- }
- }
-
-
-
-
-
- int stack_empty(void)
- {
- if(top < 0)
- return 1;
- else
- return 0;
- }
在Linux终端下编译通过后并执行文件:
gcc deepth_fisrt.c -o deepth_fisrt
./deepth_fisrt > all.txt
all.txt内容如下:
- 2 1 0 0 0
- 2 1 0 1 0
- 0 0 0 0 0
- 0 1 1 1 0
- 0 0 0 0 0
- ----------------------------------
- 2 1 0 0 0
- 2 1 0 1 0
- 2 0 0 0 0
- 0 1 1 1 0
- 0 0 0 0 0
- ----------------------------------
- 2 1 0 0 0
- 2 1 0 1 0
- 2 2 0 0 0
- 2 1 1 1 0
- 0 0 0 0 0
- ----------------------------------
- 2 1 0 0 0
- 2 1 0 1 0
- 2 2 0 0 0
- 2 1 1 1 0
- 2 0 0 0 0
- ----------------------------------
- 2 1 0 0 0
- 2 1 0 1 0
- 2 2 0 0 0
- 2 1 1 1 0
- 2 2 0 0 0
- ----------------------------------
- 2 1 0 0 0
- 2 1 0 1 0
- 2 2 0 0 0
- 2 1 1 1 0
- 2 2 2 0 0
- ----------------------------------
- 2 1 0 0 0
- 2 1 0 1 0
- 2 2 0 0 0
- 2 1 1 1 0
- 2 2 2 2 0
- ----------------------------------
- 2 1 0 0 0
- 2 1 0 1 0
- 2 2 0 0 0
- 2 1 1 1 0
- 2 2 2 2 2
- ----------------------------------
- 2 1 0 0 0
- 2 1 0 1 0
- 2 2 0 0 0
- 2 1 1 1 2
- 2 2 2 2 2
- ----------------------------------
- 2 1 0 0 0
- 2 1 0 1 0
- 2 2 0 0 2
- 2 1 1 1 2
- 2 2 2 2 2
- ----------------------------------
- 2 1 0 0 0
- 2 1 0 1 2
- 2 2 0 2 2
- 2 1 1 1 2
- 2 2 2 2 2
- ----------------------------------
- 2 1 0 0 2
- 2 1 0 1 2
- 2 2 0 2 2
- 2 1 1 1 2
- 2 2 2 2 2
- ----------------------------------
- 2 1 0 2 2
- 2 1 0 1 2
- 2 2 0 2 2
- 2 1 1 1 2
- 2 2 2 2 2
- ----------------------------------
- 2 1 2 2 2
- 2 1 0 1 2
- 2 2 0 2 2
- 2 1 1 1 2
- 2 2 2 2 2
- ----------------------------------
- 2 1 2 2 2
- 2 1 2 1 2
- 2 2 0 2 2
- 2 1 1 1 2
- 2 2 2 2 2
- ----------------------------------
- 2 1 2 2 2
- 2 1 2 1 2
- 2 2 2 2 2
- 2 1 1 1 2
- 2 2 2 2 2
- ----------------------------------
- 2 1 2 2 2
- 2 1 2 1 2
- 2 2 2 2 2
- 2 1 1 1 2
- 2 2 2 2 2
- ----------------------------------
- 2 1 2 2 2
- 2 1 2 1 2
- 2 2 2 2 2
- 2 1 1 1 2
- 2 2 2 2 2
- ----------------------------------
- 2 1 2 2 2
- 2 1 2 1 2
- 2 2 2 2 2
- 2 1 1 1 2
- 2 2 2 2 2
- ----------------------------------
- 2 1 2 2 2
- 2 1 2 1 2
- 2 2 2 2 2
- 2 1 1 1 2
- 2 2 2 2 2
- ----------------------------------
多了几行。
从左下角到右下角深度优先一个通路代码只需要将从左下角到右下角所有的通路代码中void go_maze(void);函数中if语句的注释取消即可:
- while(!stack_empty()){
-
- p = stack_pop();
-
-
-
-
-
- if(p.col < COL - 1 && ROAD == maze[p.row][p.col + 1]){
- maze_visit(p.row, p.col + 1, p);
- }
在Linux终端下编译通过后并执行文件:
gcc deepth_fisrt.c -o deepth_fisrt
./deepth_fisrt > once.txt
once.txt内容如下:
- 2 1 0 0 0
- 2 1 0 1 0
- 0 0 0 0 0
- 0 1 1 1 0
- 0 0 0 0 0
- ----------------------------------
- 2 1 0 0 0
- 2 1 0 1 0
- 2 0 0 0 0
- 0 1 1 1 0
- 0 0 0 0 0
- ----------------------------------
- 2 1 0 0 0
- 2 1 0 1 0
- 2 2 0 0 0
- 2 1 1 1 0
- 0 0 0 0 0
- ----------------------------------
- 2 1 0 0 0
- 2 1 0 1 0
- 2 2 0 0 0
- 2 1 1 1 0
- 2 0 0 0 0
- ----------------------------------
- 2 1 0 0 0
- 2 1 0 1 0
- 2 2 0 0 0
- 2 1 1 1 0
- 2 2 0 0 0
- ----------------------------------
- 2 1 0 0 0
- 2 1 0 1 0
- 2 2 0 0 0
- 2 1 1 1 0
- 2 2 2 0 0
- ----------------------------------
- 2 1 0 0 0
- 2 1 0 1 0
- 2 2 0 0 0
- 2 1 1 1 0
- 2 2 2 2 0
- ----------------------------------
- 2 1 0 0 0
- 2 1 0 1 0
- 2 2 0 0 0
- 2 1 1 1 0
- 2 2 2 2 2
- ----------------------------------
数组中2表示走过的路,那么从左上角严着有2的路线到右下角都是迷宫中的通道。如果寻找通道的方法不变(右,下,左,上),继续寻找新道路的顺序也变为右,下,左,上,那么就可以实现广度优先搜索。队列就有先进先出的特性,故而只要将以上代码的数据结构换成队列,那么就可以实现广度优先搜索来解决迷宫问题。一般为了回收利用队列中的存储空间,会采用环形队列作为程序数据结构来解决问题。除此之外,在堆栈数据结构上改变寻找通道的顺序也可以实现广度优先搜索,队列也可以实现深度优先搜索(未编程验证)。