标签:
迷宫问题中为了保证任何位置上都能沿原路退回,显然需要用一个先进后出的结果来保存从入口到当前位置的路径。因此,在迷宫通路的算法中应用“栈”也是自然而然的事情
头文件:
#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; }
运行结果:
上述实心笑脸表示墙,空心笑脸表示此路可行,最终形成的空白是从起点到终点的通路
标签:
原文地址:http://www.cnblogs.com/csudanli/p/4808870.html