/* 三江学院 电子信息工程 文件名:use.c 摘要:经典的迷宫问题,通过数据结构————“栈”和回朔思想,解决迷宫问题。 完成日期:2012-7-1 23:55 作者:黄路 当前版本:1.2 */ #include <stdio.h> #include "stack.h" //定义一个迷宫数组,1代表障碍,0代表畅通 int maze[M][N] = { 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0}; seqstack seq;//栈 seqstack *s; //栈指针 datatype temp; //当前数据结点 int main() { //int i = 0; //int j = 0; int r = 0; //每次移动的方向 x, y, d // j, i datatype move[4] = {0, 1, 0, "RIGHT", 1, 0, 1, "DOWN", 0, -1, 2, "LEFT", -1, 0, 3, "UP"}; s = &seq; r = mazepath(maze, move);//找迷宫的一条有效路径 if(r == 1) { printf("the valid paht is (step from exit to entry):\n"); while(!empty_stack(s)) { pop_stack(s, &temp);//将出栈值放入temp中,并打印内容 printf("<%d, %2d>, %s\n", temp.x, temp.y, move[temp.d].dir); } } else { printf("there is not a valid path!\n"); } return 0; }
/* 三江学院 电子信息工程 文件名:stack.h 摘要:全局变量定义,函数声明,栈结构定义,数据元素定义 完成日期:2012-7-1 23:55 作者:黄路 当前版本:1.2 */ #ifndef STACK_H_INCLUDED #define STACK_H_INCLUDED #define M 6//迷宫实际的行数 #define N 6 // 迷宫实际的列数 #define MAXSIZE 2000//栈最大的深度 /* 数据元素 x,y描述它的位置; d描述它的前行方向 ; dir对d的文字表述 */ typedef struct datatype { int x; int y; int d; char dir[6]; }datatype; /* data[]是栈元素; top是栈序号,即某个元素在栈中的位置! */ typedef struct seqstack { datatype data[MAXSIZE]; int top; }seqstack; //寻找迷宫的一条路径 int mazepath(int maze[][N], datatype *move); //进栈 int push_stack(seqstack *s, datatype x); //判断栈是否为空 int empty_stack(seqstack *s); //出栈 int pop_stack(seqstack *s, datatype *x); #endif // STACK_H_INCLUDED
/* 三江学院 电子信息工程 文件名:stack.c 摘要:函数定义,包括路径查找,入栈,出栈,空栈判断 完成日期:2012-7-1 23:55 作者:黄路 当前版本:1.2 */ #include <stdio.h> #include "stack.h" //方向定义 #define RIGHT 0 #define DOWN 1 #define LEFT 2 #define UP 3 #define DIRECTIONS 4 seqstack seq; seqstack *s; datatype temp; /* 设计思路——回朔: 如果当前结点可走,标记走过的方向,入栈,进入下一结点,且每个结点都是依据右,下, 左,上的次序 来遍历的,如果当前结点不可走,出栈,遍历,直到找到出口,或者栈空为止。 */ int mazepath(int maze[][N], datatype move[]) { //表示当前的横纵坐标 int x = 0; int y = 0; //i , j 表示下一个可走的坐biao; 表示方向 int d = -1; int i = 0; int j = 0; //初始化入口 temp.x = 0; temp.y = 0; temp.d = -1; maze[0][0] = -1; //标识已走过的路径 push_stack(s, temp);// 将temp之压入栈 while(!empty_stack(s)) { pop_stack(s, &temp);//将出栈值存入temp,进行处理 x = temp.x; y = temp.y; d = temp.d + 1; //变向 while(d < DIRECTIONS)//依次遍历4个方向寻找可以走通的路径 { /* funtions:for location if it reaches the boundary, it will change directions in the order of RIGHT, DOWN, LEFT,UP. otherwise, go right, j + 1; go left, j - 1; go up, i - 1; go down, i + 1; */ switch(d) { case RIGHT : if (y == N - 1) //纵坐标,N代表列数 { d++; //右边到达边界了 } else { j = y + move[d].y; //j = 1 } i = x + move[d].x; //i = 0 break; case DOWN : if (x == M - 1) //下边界了 { d++; } else { i = x + move[d].x; //i = 1 } j = y + move[d].y; //j = 0 break; case LEFT : if (x == 0) //左边界了 { d++; } else { i = x + move[d].x; //i = -1 } j = y + move[d].y; //j = 0 break; case UP : if (y == 0) //上边界了 { d++; } else { j = y + move[d].y; //j = -1 } i = x + move[d].x; //i = 0 break; default : printf("direction error!\n"); break; } if (maze[i][j] == 0) //next direction is securable { //保存当前位置,入栈 temp.x = x; temp.y = y; temp.d = d; maze[x][y] = -1; //mark visitd position push_stack(s, temp); //push temp into stack //进入下一个位置 x = i; y = j; //判断是否找到出口? if ((x + 1) == M && (y + 1) == N) //find one pace { return 1; } else { d = 0;//重新开始遍历 } } else { d++; //当前方向没有找到可以走的点,于是改变方向 } } } return 0; } /* 入栈 输入:栈指针seqstack *s,结点datatype x 输出:1,表示入栈成功,0表示入栈失败; */ int push_stack(seqstack *s, datatype x) { //上溢 保护 if ( MAXSIZE - 1 == s->top ) { return 0; } else { s->top++; //栈顶上移 s->data[s->top] = x; return 1; } } /* 判断栈是否为空 ,目的是防止‘下 溢’ 输入:栈指针seqstack *s 返回:1,表示栈空;0,表示栈非空。 */ int empty_stack(seqstack *s) { if (0 == s->top) { return 1; } else { return 0; } } /* 出栈 输入:栈指针sqstack *s,结点指针datatype *x */ int pop_stack(seqstack *s, datatype *x) { if(empty_stack(s)) { return 0; } else { *x = s->data[s->top]; //修改了结点指针,它是个全局变量 s->top--; return 1; } }