/*
三江学院 电子信息工程
文件名: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;
}
}