C语言没有自己的栈操作的一系列库函数,如果是C++,可以使用STL,所以自己用了自己以前写的栈函数。
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
typedef int NextDirectionType;
typedef struct{
int row;
int col;
}PosType;
typedef struct{
PosType seat;//当前的位置信息
NextDirectionType dir;//选择下一个位置的方向,分别为东南西北
}element;
//建立顺序栈
#define STACK_INIT_SIZE 100
#define STACKINCRESEMENT 10
typedef element DataType ;
typedef struct SqStack
{
DataType *base;
DataType *top;
int stacksize;
}SqStack,* pSqStack;
//函数声明
pSqStack InitStack();
DataType GetTop(pSqStack s);
int IsStackEmpty(pSqStack s);
void Push( pSqStack s,DataType x);
void Pop(pSqStack s,DataType *x);
int GetStackSize(pSqStack s);
void ClearStack(pSqStack s);
void DestroyStack(pSqStack s);
void Visit(int data);
void StackTraverseFromBase(pSqStack s);
pSqStack InitStack()
{
pSqStack s=(pSqStack) malloc(sizeof(SqStack));
if(! s)
return NULL;
s->base=(DataType *) malloc(sizeof(DataType) *STACK_INIT_SIZE);
if(! s->base)
exit(-1);
s->top=s->base;
s->stacksize=STACK_INIT_SIZE;
return s;
}
DataType GetTop(pSqStack s)
{
if( !s)
{
printf("the stack initialization failed \n");
exit(-1);
}
if(s->base==s->top)
{
printf("the stack is null\n");
return ;
}
return *(s->top-1);
// return *(--s->top);
// return s->base[--s->top];
}
int IsStackEmpty(pSqStack s)
{
if( !s)
{
printf("the stack initialization failed \n");
exit(-1);
}
if(s->base==s->top)
{
return 1;
}
return 0;
}
void Push( pSqStack s,DataType x)
{
if( (s->top-s->base) >=s->stacksize)
{
s->base=(DataType *) realloc( s->base,(STACK_INIT_SIZE+STACKINCRESEMENT)*sizeof(DataType) ) ;
if( !s->base)
exit(-1);
s->top=s->base + s->stacksize;
s->stacksize+=STACKINCRESEMENT;
}
* s->top=x;
s->top++;
}
void Pop(pSqStack s,DataType *x)
{
if(s->base==s->top)
printf("the stack is null,can't pop anything\n");
// *x=s->base[--s->top];
if(x!=NULL) // 为了和栈清空结合起来
*x= *(--s->top);
else
--s->top;
}
int GetStackSize(pSqStack s)
{
if(!s)
exit(-1);
return s->stacksize;
}
void ClearStack(pSqStack s)
{
if(!s)
exit(-1);
while(s->base !=s->top) //或者 while( !IsSatckEmpty(s))
{
Pop(s, NULL);
}
}
void DestroyStack(pSqStack s)
{
if( !s)
exit(-1);
free(s->base);
free(s);
}
void Visit(int data)
{
printf("%d ",data);
}
void StackTraverseFromBase(pSqStack s)
{
DataType *p=s->base;
DataType data;
while(p!=s->top)
{
char ch[4][4]={"->","↓","<-","↑"};
printf("(%d %d) 下一个位置的方向 :%s\n",(*p).seat.row, (*p).seat.col,ch[ (*p).dir ]);
p++;
}
}
//Maze.c
//Maze.c
//-------------------- 迷宫程序 ----------------------------------
/**//**************************************************************
迷宫问题算法: 从入口出发,顺着某一个方向进行探索,若能走通,则继续
前进;否则沿着原路退回,换一个方向继续探索,直至出口位置,求得一条通路,
假如所有可能的通路都探索到而未能达到出口,则所设定的迷宫没有通路.
说明:可通: 未增走到过的通道快.
*********************************************************/
#include<stdio.h>
#include"SqStack.c"
#define M 5
#define N 5
#define EXIT_ROW M
#define EXIT_COL N
#define true 1
#define false 0
typedef int bool;
//其中element结构体在SqStack中,因为对栈操作中用到了它
typedef struct{
int horiz; //水平方向
int vert; //垂直方向
}offsets;
offsets move[4]=
{
//这里注意它的方向东南西北和你用坐标表示(x,y),那种记法不一样,得从数组上来看a[i][j]中的i,j变化
{0, 1},//东
{1, 0},//南
{0,-1},//西
{-1, 0} //北
};
int maze[M+2][N+2]; //迷宫的大小,为了防止边界检查,把四周都设置为1,即有墙
int mark[M+2][N+2]={0}; //标记走过的路径中的0,以免重复走该路径
//函数声明
void InitMaze();
void PrintMaze();
void MazePath();
//随机生成迷宫
void InitMaze()
{
int i,j;
srand((unsigned int) time(NULL));
for(i=1;i<=M ;i++)
for(j=1;j<=N;j++)
{
maze[i][j]=rand()%2;
}
maze[1][1]=0;//起始结点要为0,否则随机产生的迷宫没有意义
maze[M][N]=0;
//加上围墙
//对行加围墙
for(j=0; j<N+2 ;j++)
maze[0][j]=1;
for(j=0; j<N+2 ;j++)
maze[M+2-1][j]=1;
//对列加围墙
for(i=0; i<M+2;i++)
maze[i][0]=1;
for(i=0; i<M+2 ;i++)
maze[i][N+2-1]=1;
}
//打印迷宫
void PrintMaze()
{
int x,y;
x=1;
y=1;
printf("起点位置 :(%d %d).\n",x,y);
x=M;
y=N;
printf("终点位置 :(%d %d).\n",x,y);
printf("The maze :\n");
int i,j;
srand((unsigned int) time(NULL));
for(i=0;i<M+2 ;i++)
{
for(j=0;j<N+2;j++)
{
printf("%d ",maze[i][j]);
}
printf("\n");
}
printf("\n");
}
void MazePath()
{
mark[1][1]=1;
bool find=false;
pSqStack s=InitStack();
element info ;
info.seat.row=1;
info.seat.col=1;
info.dir=0;
Push(s,info);
while(! IsStackEmpty(s))
{
Pop(s,&info);
int row=info.seat.row;
int col=info.seat.col;
int dir=info.dir;
while( dir <4 && !find)
{
int next_row=row+move[dir].horiz; //下一个位置的row
int next_col=col+move[dir].vert; //下一个位置的col
if(next_row==EXIT_ROW && next_col==EXIT_COL) //下一个位置为出口,则找到
{
find=true;
info.seat.row=row; //把当前位置入栈,其实这4句不加入也可以,只是为了输出结果好看
info.seat.col=col; //否则离出口的前一步的位置没有输出。
info.dir=dir;
Push(s,info);
}
else if(maze[next_row][next_col]==0 && mark[next_row][next_col]==0) //下一个位置为不是出口,且该路径没有走过
{
maze[next_row][next_col]=1;
info.seat.row=row; //把当前位置入栈
info.seat.col=col;
info.dir=dir;
Push(s,info);
row=next_row;//把下一个位置置为当前位置
col=next_col;
dir=0; //且此时下一个位置方向重新选择
}
else
dir++;
}
if(find)
{
printf("The path is :\n");
StackTraverseFromBase(s);//把栈里面所存的路径输出,自栈底向栈顶输出
printf("(%d %d )终点\nGet the exit.Success!\n",EXIT_ROW,EXIT_COL);
DestroyStack(s);//此时找到了,栈空间要释放。
return;
}
}
printf("The maze doesn't have a path\n");
DestroyStack(s);
}
//test
int main()
{
InitMaze();
PrintMaze();
MazePath();
return 1;
}