子函数
stack.h
// - - - - - 栈的顺序存储表示 - - - - -
#define STACK_INIT_SIZE 100 //存储空间初始分配量
#define STACKINCERMENT 10 //存储空间分配增量
typedef bool Status;
typedef struct {
SElemType* base; //在栈构造之前和销毁之后,base的值为NULL
SElemType* top; //栈顶指针
int stacksize; //当前已分配的储存空间,以元素为单位
}SqStack;
// - - - - - 基本操作的函数原型说明 - - - - -
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 Push(SqStack& S, SElemType e);
//插入元素e为新的栈顶元素
Status Pop(SqStack& S, SElemType& e);
//若栈不空,删除S的栈顶元素,用e返回其值,并返回true;否则返回false
// - - - - - 基本操作的算法描述(部分) - - - - -
Status InitStack(SqStack& S) {
S.base = (SElemType*)malloc(STACK_INIT_SIZE * sizeof(SElemType));
if (!S.base) exit(OVERFLOW); //存储分配失败
S.top = S.base;
S.stacksize = STACK_INIT_SIZE;
return true;
}// InitStack
Status DestroyStack(SqStack& S) {
ClearStack(S);
free(S.base);
S.top = S.base = NULL;
S.stacksize = 0;
return true;
}// DestroyStack
Status ClearStack(SqStack& S) {
if (S.top = S.base)
return true;
while (S.top != S.base) {
S.top->ord = S.top->di = S.top->seat.x = S.top->seat.y = 0;
S.top--;
}
S.top->ord = S.top->di = S.top->seat.x = S.top->seat.y = 0;
S.base = S.top;
return true;
}// ClearStack
Status StackEmpty(SqStack S) {
if (S.top == S.base)
return true;
else
return false;
}// StackEmpty
int StackLength(SqStack S) {
SElemType* p = S.top; int i = 0;
while (p != S.base) {
p--;
i++;
}
return i;
}
Status Push(SqStack& S, SElemType e) {
if (S.top - S.base >= STACK_INIT_SIZE) { //栈满,追加存储空间
S.base = (SElemType*)realloc(S.base, (S.stacksize + STACKINCERMENT) * sizeof(SElemType));
if (!S.base) exit(OVERFLOW); //存储分配失败
S.top = S.base + S.stacksize;
S.stacksize += STACKINCERMENT;
}
*S.top = e;
S.top++;
return true;
}// Push
Status Pop(SqStack& S, SElemType& e) {
if (S.top == S.base)
return false;
S.top--;
e = *S.top;
return true;
}// Pop
maze.h
#define M 25
#define N 25
typedef int** MazeType;//定义迷宫类型为二维数组指针
typedef struct {
int x; //横坐标
int y; //纵坐标
}PosType; //坐标位置的元素类型
typedef struct {
int ord; //通道块在路径上的“序号”
PosType seat; //通道块在迷宫中的“坐标位置”
int di; //从此通道块走向下一通道块的方向
}SElemType; //栈的元素类型
#include "stack.h"
// - - - - - 基本操作的函数原型说明 - - - - -
Status InitMaze(MazeType& maze);
//初始化迷宫
Status DestroyMaze(MazeType& maze);
//销毁迷宫
Status ClearMaze(MazeType& maze);
//清空迷宫
Status CreateMaze(MazeType& maze, int m, int n);
//随机生成长m+1宽n+1的迷宫,0墙1路,迷宫边界是墙
Status PrintMaze(MazeType maze, int m, int n);
//打印迷宫, X代表墙,*代表路
Status Pass(MazeType maze, PosType p);
//若当前位置p可以通过且未走过,maze[p.x][p.y]=1,则返回true;
//否则返回false
void FootPrint(MazeType& maze, PosType p);
//留下足迹,当前位置p已经走过,maze[p.x][p.y]=2
void MarkPrint(MazeType& maze, PosType p);
//留下不能通过的标记,maze[p.x][p.y]=0
PosType NextPos(PosType p, int di);
//返回当前位置p的下一位置,东di=1,南di=2,西di=3,北di=4
SElemType SetCurSElem(int ord, PosType seat, int di);
//返回对应序号ord坐标seat及方向di的栈的元素
Status MazePath(SqStack& S, MazeType maze, PosType start, PosType end);
//若迷宫maze存在从入口start到出口end的通道,则求得一条存放在栈中
//(从栈底到栈顶),并返回true;否则返回false
// - - - - - 基本操作的算法描述 - - - - -
Status InitMaze(MazeType& maze) {
int i;
maze = (int**)malloc(M * sizeof(int*));
if (!maze) exit(OVERFLOW);
for (i=0; i < M; i++) {
maze[i] = (int*)malloc(N * sizeof(int));
if (!maze[i]) exit(OVERFLOW);
}
return true;
}
Status DestroyMaze(MazeType& maze) {
ClearMaze(maze);
free(maze);
return true;
}
Status ClearMaze(MazeType& maze) {
for (int i = 0; i < M; i++)
free(maze[i]);
return true;
}
Status CreateMaze(MazeType& maze, int m, int n) {
int i, j;
for (i = 0; i <= m; i++) {
maze[i][0] = 0;
maze[i][n] = 0;
for (j = 1; j < n; j++) {
if (!i || i == m) maze[i][j] = 0;
else maze[i][j] = rand() % 2;
}
}
return false;
}
Status PrintMaze(MazeType maze, int m, int n) {
int i, j;
cout << "迷宫高" << m + 1 << "宽" << n + 1 << endl;
for (i = 0; i <= m; i++) {
for (j = 0; j <= n; j++) {
if (!maze[i][j]) cout << 'X';
else if(maze[i][j]==1) cout << '*';
else cout << '#';
}
cout << '\n';;
}
return true;
}
Status Pass(MazeType maze, PosType p) {
if (maze[p.y][p.x] == 1)
return true;
return false;
}
void FootPrint(MazeType& maze, PosType p) {
maze[p.y][p.x] = 2;
}
void MarkPrint(MazeType& maze, PosType p) {
maze[p.y][p.x] = 0;
}
PosType NextPos(PosType p, int di) {
switch (di){
case 1:p.x++; break;
case 2:p.y++; break;
case 3:p.x--; break;
case 4:p.y--; break;
}
return p;
}
SElemType SetCurSElem(int ord, PosType seat, int di) {
SElemType s;
s.ord = ord;
s.seat.x = seat.x; s.seat.y = seat.y;
s.di = di;
return s;
}
Status MazePath(SqStack& S, MazeType maze, PosType start, PosType end) {
InitStack(S); PosType curpos = start; //设定当前位置为入口位置
SElemType e; int curstep = 1; //探索第一步
do {
if (Pass(maze, curpos)) {
FootPrint(maze, curpos);
e = SetCurSElem(curstep, curpos, 1);
Push(S, e);
if (curpos.x == end.x && curpos.y == end.y)
return true;
curpos = NextPos(curpos, 1);
curstep++;
}//if
else {
if (!StackEmpty(S)) {
Pop(S, e);
while (e.di == 4 && !StackEmpty(S)) {
MarkPrint(maze, e.seat); Pop(S, e);
}//while
if (e.di < 4) {
e.di++; Push(S, e);
curpos = NextPos(e.seat, e.di);
}//if
}//if
}//else
} while (!StackEmpty(S));
return false;
}
主函数
Project3.2.4maze.cpp
#include <iostream>
using namespace std;
#include "maze.h"
#include <time.h>
int main(){
srand((unsigned int)time(0));
SqStack S;
MazeType maze; PosType start, end;
int i = 0, m, n;
cout << "输入m n,迷宫高m+1宽n+1:\n";
cin >> m >> n;
InitMaze(maze); CreateMaze(maze, m, n);
cout << "输出迷宫(X墙*路):\n";
PrintMaze(maze, m, n);
cout << "输入入口出口坐标(左上角为0 0右下角n" << n << 'm' << m << "):\n";
cin >> start.x >> start.y >> end.x >> end.y;
while (!MazePath(S, maze, start, end)) {
cout << "迷宫不能通过\n重新生成迷宫(X墙*路):\n";
CreateMaze(maze, m, n);
PrintMaze(maze, m, n);
cout << "重新输入坐标(左上角为0 0右下角n" << n << 'm' << m << "):\n";
cin >> start.x >> start.y >> end.x >> end.y;
DestroyStack(S);
}
SElemType* p = S.base;
while (p != S.top) {
cout << p->ord << ":(" << p->seat.x << ',' << p->seat.y << ')';
switch (p->di) {
case 1:cout << "东"; break;
case 2:cout << "南"; break;
case 3:cout << "西"; break;
case 4:cout << "北"; break;
}
i++;
if (i % 4 == 0)
cout << '\n';
p++;
}
cout << "\n输出走过的迷宫\nX 墙和死路; * 没有走的路; # 通路:\n";
PrintMaze(maze, m, n);
DestroyMaze(maze);
return 0;
}
测试实例
简单优化