您的位置:首页 > 其它

用栈实现的迷宫问题

2015-09-14 23:23 501 查看
迷宫问题中为了保证任何位置上都能沿原路退回,显然需要用一个先进后出的结果来保存从入口到当前位置的路径。因此,在迷宫通路的算法中应用“栈”也是自然而然的事情

头文件:

#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define MYOVERFLOW -2
typedef int Status;
typedef struct{
int x;      //通道块位置的横坐标
int y;      //通道块位置的纵坐标
char flag;  //通道块是否可行的标志
}PoseType;
typedef struct{
int ord;         //通道块在路径上的”序号“
PoseType seat;   //通道块在迷宫中的”坐标位置“
int di;          //从此通道块走向下一通道块的”方向“
}SElemtype;          //栈的元素类型
typedef struct{
SElemtype *base;//在栈构造之前和销毁之后,base的值为NULL
SElemtype *top;//栈顶!d=====( ̄▽ ̄*)b指针
int stacksize;//当前已分配的空间储存,以元素为单位
}SqStack;
//-------基本操作的函数原型说明--------
Status visit(SqStack S);//对栈进行遍历
void Create_Stack(SqStack &S);//创建一个栈
Status InitStack(SqStack &S);//构造一个空栈S
Status DestroyStack(SqStack &S);//销毁栈S,S不再存在
Status ClearStack(SqStack &S);//把S置为空栈
Status StackEmpty(SqStack S);//若栈S为空栈,则返回TRUE,否则返回FALSE
int StackLength(SqStack S);//返回S的元素个数,即栈的长度
Status GetTop(SqStack S, SElemtype &e);
//若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR
Status Push(SqStack &S, SElemtype e);
//插入元素e为新的栈顶元素
Status Pop(SqStack &S, SElemtype &e);
//若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR
Status StackTraverse(SqStack S, Status(*visit)(SqStack S));
//从栈底到栈顶依次对栈中每个元素调用函数visit()一旦visit()失败,则操作失败
void maze();//一个迷宫,求它从起点到终点的路径


上述操作的实现:

#include "stdafx.h"
Status InitStack(SqStack &S)//构造一个空栈S
{
S.base = (SElemtype *)malloc(STACK_INIT_SIZE*sizeof(SElemtype));
if (!S.base)exit(MYOVERFLOW);
S.top = S.base;
S.stacksize = STACK_INIT_SIZE;
return OK;
}
Status DestroyStack(SqStack &S)//销毁栈S,S不再存在
{
for (; S.top != S.base;){
SElemtype *temp = S.top;
S.top--;
delete temp;
}
delete S.base;
S.stacksize = 0;
return OK;
}
Status ClearStack(SqStack &S)//把S置为空栈
{
S.top = S.base;
return OK;
}
Status StackEmpty(SqStack S)//若栈S为空栈,则返回TRUE,否则返回FALSE
{
if (S.top == S.base)return TRUE;
else return FALSE;
}
int StackLength(SqStack S)//返回S的元素个数,即栈的长度
{
int length = 0;
for (; S.top != S.base; S.top--)length++;
return length;
}
Status GetTop(SqStack S, SElemtype &e)
//若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR
{
if (S.top != S.base){
e = *(S.top - 1);
return OK;
}
else return ERROR;

}
Status Push(SqStack &S, SElemtype e)
//插入元素e为新的栈顶元素
{
if (S.top - S.base >= S.stacksize){
S.base = (SElemtype *)realloc(S.base, (S.stacksize + STACKINCREMENT)*sizeof(SElemtype));
if (!S.base)exit(MYOVERFLOW);
S.top = S.base + S.stacksize;
S.stacksize += STACKINCREMENT;
}
*(S.top++) = e;
return OK;
}
Status Pop(SqStack &S, SElemtype &e)
//若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR
{
if (S.top != S.base){
e = *(--S.top);
return OK;
}
else return ERROR;
}
Status visit(SqStack S)//对栈进行遍历1
{
if (S.base){
cout << "the data of the Stack is:";
for (; S.top != S.base;)
{
--S.top;
cout << S.top->di << " " << S.top->ord << " " << S.top->seat.x << ',' << S.top->seat.y <<S.top->seat.flag<< endl;
}
return OK;
}
else return ERROR;
}
Status StackTraverse(SqStack S, Status(*visit)(SqStack))
//从栈底到栈顶依次对栈中每个元素调用函数visit()一旦visit()失败,则操作失败
{
if (visit(S))return OK;
return ERROR;
}
void Create_Stack(SqStack &S)//创建一个栈
{
InitStack(S);
cout << "please input the length of the Stack:";
int len;
cin >> len;
cout << "please input the data of the Stack:";
for (int i = 1; i <= len; i++){
SElemtype temp;
cin >> temp.di>>temp.ord>>temp.seat.x>>temp.seat.y>>temp.seat.flag;
Push(S, temp);
}
}
void maze()//一个迷宫,求它从起点到终点的路径
{
PoseType map[8][8];
srand((int)time(0));
for (int i = 0; i <= 7; i++)//构造地图
{
cout << "                         ";
for (int j = 0; j <= 7; j++)
{
map[i][j].flag = 2;
map[i][j].x = i;
map[i][j].y = j;
double ran = rand() / (RAND_MAX + 1.0);
if (ran<= 0.7)map[i][j].flag = 1;//在这个地图中,墙所占的比例为30%
cout << map[i][j].flag<< " ";
}
cout << endl;
}
cout << endl << endl << endl << endl;
map[0][0].flag =0;//起点为地图的左上角
map[7][7].flag = 1;//终点为地图的右下角
int t = 1;//是迷宫路径上的第几块通道
SqStack sq;
InitStack(sq);//构造一个空的栈
SElemtype first;
first.di = 0;
first.ord = t;
first.seat = map[0][0];
Push(sq, first);//将起点放到栈中
do{
SElemtype way, nextstep;
Pop(sq,way);
switch (way.di)
{
case 0:if (way.seat.y < 7 && map[way.seat.x][way.seat.y+1].flag==1){//如果上个通道块的di为0,则地图向右扩展
nextstep.di = 0;//新的通道块的di=0;是第++t个通道块,通道块的flag标志为0,说明此通道块被扩展
nextstep.ord = ++t;
map[way.seat.x][way.seat.y + 1].flag = 0;
nextstep.seat = map[way.seat.x][way.seat.y+1];
way.di++;//上个通道块的di++,说明右边的通道块已经被扩展
Push(sq, way);
Push(sq, nextstep);//将上个通道块和新的通道块都压入栈中
if (nextstep.seat.x == 7 && nextstep.seat.y == 7)goto label;//如果是终点,则跳出循环
break;
}
else {                                              //如果向右不能扩展,则di++,并将上个通道块压入栈
way.di++; Push(sq, way); break;
}
case 1:if(way.seat.x < 7 && map[way.seat.x+1][way.seat.y].flag == 1){//同case 0,这是向下扩展
nextstep.di = 0;
nextstep.ord = ++t;
map[way.seat.x+1][way.seat.y].flag = 0;
nextstep.seat = map[way.seat.x+1][way.seat.y];
way.di++;
Push(sq, way);
Push(sq, nextstep);
if (nextstep.seat.x == 7 && nextstep.seat.y == 7)goto label;
break;
}
else {
way.di++;
Push(sq, way); break;
}
case 2:if (way.seat.y >0 && map[way.seat.x ][way.seat.y- 1].flag == 1){//同case 0,这是向左扩展
nextstep.di = 0;
nextstep.ord = ++t;
map[way.seat.x][way.seat.y - 1].flag = 0;
nextstep.seat = map[way.seat.x][way.seat.y - 1];
way.di++;
Push(sq, way);
Push(sq, nextstep);
if (nextstep.seat.x == 7 && nextstep.seat.y == 7)goto label;
break;
}
else {
way.di++;
Push(sq, way); break;
}
case 3:if (way.seat.x > 0 && map[way.seat.x-1 ][way.seat.y].flag == 1){//同case 0,这是向上扩展
nextstep.di = 0;
nextstep.ord = ++t;
map[way.seat.x-1][way.seat.y].flag = 0;
nextstep.seat = map[way.seat.x-1 ][way.seat.y];
way.di++;
Push(sq, way);
Push(sq, nextstep);
if (nextstep.seat.x == 7 && nextstep.seat.y == 7)goto label;
break;
}
else {
way.di++;
Push(sq, way); break;
}
default:                                         //如果该通道块4个方向上已经被扩展完毕,则将这个通道块的flag设置为3,说明已经被扩展,但此路不通
map[way.seat.x][way.seat.y].flag = 3;
t--;
break;
}
} while (!StackEmpty(sq));//当栈为空时,说明没有通路,跳出循环
label:
if (StackEmpty(sq)){ cout << "there is no way in the maze!"; exit(-1); }
for (int i = 0; i <= 7; i++)
{
cout << "                         ";
for (int j = 0; j <= 7; j++)
{
cout << map[i][j].flag << " ";
}
cout << endl;
}
}


主函数:

// maze.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

int _tmain(int argc, _TCHAR* argv[])
{
maze();
return 0;
}


运行结果:





上述实心笑脸表示墙,空心笑脸表示此路可行,最终形成的空白是从起点到终点的通路
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: