欢迎光临散文网 会员登陆 & 注册

《数据结构(C语言版)》栈的应用之迷宫求解

2022-03-29 21:00 作者:回到唐朝当少爷  | 我要投稿

清华大学计算机系列教材   累计发行超400万册

严蔚敏 吴伟明 编著

数据结构(C语言版) 

以下是本人对紫皮书第三章3.2节栈的应用举例中3.2.4迷宫求解的代码,3.2.1数制转换、3.2.2括号匹配的检验、3.2.3行编辑程序的代码已在上一节写出,话不多说上运行结果:

该迷宫地图与课本完全相同
最后得出迷宫的通路之一(程序是按东南西北的顺序寻找通路)
可得出每一步运行过程
您还可以修改迷宫入口的位置

可执行代码如下

(貌似专栏把我缩进吃了,懒得加了,另外建议用visual studio编译) 

#include <stdio.h>

#include <stdlib.h>

#define TRUE 1

#define FALSE 0

#define OK 1

#define ERROR 0

#define INFEASIBLE -1

#define OVERFLOW -2

#define STACK_INIT_SIZE 100//存储空间初始分配量

#define STACKINCREMENT 10//存储空间分配增量

#define LENGTH 10

#define WIDTH 10

typedef int Status;

typedef int MazeType[LENGTH][WIDTH];//迷宫大小

typedef struct

{

int row;//行

int col;//列

}PosType;

typedef struct

{

int ord;//通道块在路径上的“序号”

PosType seat;//通道快在迷宫中的“坐标位置”

int di;//从此通道块走向下一通道块的“方向”

//1表示东,2表示南,3表示西,4表示北

}SElemType;//栈的元素类型

typedef struct

{

SElemType* base;

SElemType* top;

int stacksize;

}SqStack;

void FootPrint(PosType curpos, int curstep);//留下足迹

void ShowMaze(PosType start);//打印地图

Status Pass(PosType pos);//判断当前位置是否可以通过

PosType NextPos(PosType CurPos, int i);//返回下一位置

void MarkPrint(PosType pos);//标记走不通的位置

Status MazePath(MazeType maze, PosType start, PosType end);//若迷宫中存在从入口start到出口end的通道,则求得一条存放在栈中

Status InitStack(SqStack& S);//初始化一个空栈

Status Push(SqStack& S, SElemType e);//顺序栈的入栈

Status Pop(SqStack& S, SElemType& e);//顺序栈的出栈

Status StackEmpty(SqStack S);//判断栈是否为空

//用全局变量表示迷宫地图

MazeType maze =

{

/*用0表示墙,用1表示路*/

   //0,1,2,3,4,5,6,7,8,9

{0,0,0,0,0,0,0,0,0,0}, //0

{0,1,1,0,1,1,1,0,1,0}, //1

{0,1,1,0,1,1,1,0,1,0}, //2

{0,1,1,1,1,0,0,1,1,0}, //3

{0,1,0,0,0,1,1,1,1,0}, //4

{0,1,1,1,0,1,1,1,1,0}, //5

{0,1,0,1,1,1,0,1,1,0}, //6

{0,1,0,0,0,1,0,0,1,0}, //7

{0,0,1,1,1,1,1,1,1,0}, //8

{0,0,0,0,0,0,0,0,0,0}  //9

};

int main()

{

printf("迷宫地图如下:\n");

PosType Start = { 1,1 };

PosType End = { 8,8 };

ShowMaze(Start);

if (MazePath(maze, Start, End))

{

printf("该迷宫的一条通路为:\n");

ShowMaze(Start);

}

return 0;

}

void FootPrint(PosType curpos, int curstep)//留下足迹

{

maze[curpos.row][curpos.col] = curstep;

}

void ShowMaze(PosType start)//打印地图

{

for (int i = 0; i < LENGTH; i++)

{

for (int j = 0; j < 10; j++)

{

if (i == start.row && j == start.col)//打印起始位置

{

printf("1 ");

}

else if (maze[i][j] == 0)

{

printf("■");

}

else if (maze[i][j] == 1 || maze[i][j] == -1)

{

printf("  ");

}

else

{

printf("%-2d", maze[i][j]);

}

}

printf("\n");

}

}

Status Pass(PosType pos)//判断当前位置是否可以通过

{

if (maze[pos.row][pos.col] == 1)

{

return TRUE;

}

return FALSE;

}

PosType NextPos(PosType CurPos, int i)//返回下一位置

{

switch (i)

{

case 1:

++CurPos.col;//向东走一步

break;

case 2:

++CurPos.row;//向南走一步

break;

case 3:

--CurPos.col;//向西走一步

break;

case 4:

--CurPos.row;//向北走一步

break;

}

return CurPos;

}

void MarkPrint(PosType pos)//标记走不通的位置

{

maze[pos.row][pos.col] = -1;//-1表示该位置走不通

}

Status MazePath(MazeType maze, PosType start, PosType end)//若迷宫中存在从入口start到出口end的通道,则求得一条存放在栈中

{

SqStack S;

PosType curpos;//cur为current的缩写,表示当前位置(position)

SElemType e;

int curstep;//表示当前走过的步数

InitStack(S);

curpos = start;//设定“当前位置”为“入口位置”

curstep = 1;//记录当前走过的步数

do

{

if (Pass(curpos))//当前位置可以通过,即是未曾走到过的通道块

{

FootPrint(curpos, curstep);//留下足迹

printf("step%d:\t(%d,%d)\n", curstep, curpos.col, curpos.row);

e = { curstep,curpos,1 };//1表示当前方位为东

Push(S, e);//加入路径

if (curpos.col == end.col && curpos.row == end.row)//到达终点(出口)

{

printf("到达终点:(%d,%d)\n", e.seat.col, e.seat.row);

return TRUE;

}

curpos = NextPos(curpos, 1);//下一位置是当前位置的东邻

curstep++;

//ShowMaze(start);//可以打开这一步注释看看具体每一步代码是怎么走的

}

else//当前位置不能通过

{

if (!StackEmpty(S))

{

Pop(S, e);

while (e.di == 4 && !StackEmpty(S))//如果

{

MarkPrint(e.seat);

Pop(S, e);//留下不能通过的标记,并退回一步

curstep--;

printf("倒退一步到step%d:(%d, %d)\n",curstep-1, e.seat.col, e.seat.row);

}

if (e.di < 4)

{

e.di++;//换下一个方向探索

Push(S, e);

curpos = NextPos(e.seat, e.di);//设定当前位置是该新方向上的相邻块

}

}

}

} while (!StackEmpty(S));//如果栈空表示所有方向都不通

printf("对不起,找不到出口");

return 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 OK;

}

Status Push(SqStack& S, SElemType e)//顺序栈的入栈

{

if (S.top - S.base >= S.stacksize)

{

SElemType* New_ptr = (SElemType*)realloc(S.base, ((S.stacksize) + STACKINCREMENT) * sizeof(SElemType));

if (!New_ptr)

{

exit(OVERFLOW);

}

S.base = New_ptr;

S.top = S.base + S.stacksize;

S.stacksize += STACKINCREMENT;

}

*S.top++ = e;

return OK;

}

Status Pop(SqStack& S, SElemType& e)//顺序栈的出栈

{

if (S.top == S.base)

{

return ERROR;

}

e = *--S.top;

return OK;

}

Status StackEmpty(SqStack S)//判断栈是否为空

{

if (S.top == S.base)

{

return TRUE;

}

else

{

return FALSE;

}

}


《数据结构(C语言版)》栈的应用之迷宫求解的评论 (共 条)

分享到微博请遵守国家法律