c语言的错误代码c4129,用C语言解决迷宫问题(示例代码)

本文介绍了一种使用链式栈数据结构实现的迷宫求解算法。通过定义迷宫地图和方向优先级,该算法能够自动寻找从入口到出口的路径,并在遇到障碍时回溯。文章详细解释了栈的操作过程及迷宫探索的具体步骤。

#include

#include

#define ROW 10

#define COL 10

/*迷宫中位置信息*/

typedef struct position

{

int x;

int y;

}position;

/*在迷宫中的当前位置的信息,也是入栈的基本元素*/

typedef struct SElem

{

int di;

position seat;

}SElem;

/*链式栈中节点的定义*/

typedef struct position_stack

{

SElem p;

struct position_stack *next;

}*Stack_pNode,Stack_Node;

void InitStack(Stack_pNode *Link)

{

*Link = NULL;

}

void push(Stack_pNode *Link,SElem e)

{

Stack_pNode new_SElem = (Stack_pNode)calloc(1,sizeof(Stack_Node));

new_SElem->p = e;

new_SElem->next = NULL;

if (*Link == NULL)

*Link = new_SElem;

else

{

new_SElem->next = *Link;

*Link = new_SElem;

}

}

int pop(Stack_pNode *Link,SElem *e)

{

if (*Link == NULL)

return 0;

*e = (*Link)->p;

Stack_pNode q = *Link;

*Link = (*Link)->next;

free(q);

return 1;

}

int top(Stack_pNode Link, SElem *e)

{

if (Link == NULL)

return 0;

*e = Link->p;

return 1;

}

int empty(Stack_pNode Link)

{

if (Link == NULL)

return 1;

else

return 0;

}

int reverse(Stack_pNode *Link)

{

Stack_pNode p, q, r;

if (*Link == NULL || (*Link)->next == NULL)

return 0;

r = *Link;

p = (*Link)->next;

q = NULL;

while (p){

r->next = q;

q = r;

r = p;

p = p->next;

}

r->next = q;

*Link = r;

}

void print(Stack_pNode Link)

{

Stack_pNode r = Link;

while (r){

printf("(%d,%d) -> ",r->p.seat.x,r->p.seat.y);

r = r->next;

}

printf("exit\n");

}

int curstep = 1;/*纪录当前的足迹,填写在探索前进的每一步正确的路上*/

/*迷宫地图。1代表墙的位置,0代表可行的路,周围有一圈墙*/

int m[ROW+2][COL+2] = {

1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,

1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,

1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1,

1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1,

1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1,

1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1,

1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1,

1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1,

1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1,

1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,

1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1,

1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1

};

/*方向优先级设定。依次为当前位置的右,下,左。上,在位置信息中。保存有本次

前进的方向--数组的下标*/

position dir_set[4] = { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } };

/*推断当前位置是否可行。即推断是路。还是墙*/

int pass(position p)

{

if (m[p.x][p.y])

return 0;

else

return 1;

}

/*将当前的步数填写在走的每一步正确的路上,当发现走不通时,会把当时写的信息

用‘1’抹掉,代表走不通。

*/

void footPrint(position p)

{

m[p.x][p.y] = curstep;

}

/*计算下一步的坐标。di代表方向。本函数仅仅负责计算下一步坐标。不推断优先级*/

void nextPos(position *p, int di)

{

(*p).x += dir_set[di].x;

(*p).y += dir_set[di].y;

}

/*如上面的footPrint()凝视中提到的,当发现当前路走不通时,会用‘1’把走不通的

路堵上。

*/

void markPrint(position p)

{

m[p.x][p.y] = 1;

}

/*迷宫程序的主函数。形參是一个指向不带头节点的栈的指针的指针,一个開始位置

,一个结束位置*/

int find_path(Stack_pNode * Maze_stack,position start,position end)

{

position curpos = start;/*定义一个位置变量。用来保存当前的位置信息

*/

SElem e;/*栈的元素。包含位置信息,和前进的方向*/

do

{

if (pass(curpos)){ /*假设当前节点是路,则要将当前节点入栈。

并计算下一步前进方向*/

footPrint(curpos);/*在前进节点上纪录当前的步数*/

e.seat = curpos;/*保存位置信息*/

e.di = 0;/*保存方向信息。默觉得向右*/

push(Maze_stack, e);/*将位置信息入栈*/

++curstep;/*步数加1*/

if (curpos.x == end.x && curpos.y == end.y)/*假设当

前节点是出口。则返回运行成功的标识*/

return 1;

nextPos(&curpos, e.di);/*计算下一步的坐标。是依据当

前位置信息计算的,即已经入栈了的信息*/

}

else{/*假设当前节点是墙。则须要从栈取出之前走过的路,即沿原

路返回,在返回的过程中,还要不断的推断有没有其它的路*/

if (!empty(*Maze_stack)){/*假设栈中有元素*/

pop(Maze_stack,&e);

--curstep;

while (e.di == 3 && !empty(*Maze_stack)){/*

边向前回溯,边推断是否有其它的路可走*/

markPrint(e.seat);/*用"墙"覆盖之前

填写的步数信息*/

pop(Maze_stack,&e);

--curstep;

}

if (e.di < 3){/*当找到了一个还有其它的路可

走之前走过的一个方块(最坏的情况是回到起始位置)*/

++e.di;/*按优先级改变之前的行走方向

*/

push(Maze_stack, e);/*再次入栈*/

++curstep;/*再次将步数加1*/

curpos = e.seat;/*再次纪录如今的位

置*/

nextPos(&curpos, e.di);/*再次计算下

次的方向,有了以上的准备,即将进行下一次的循环*/

}//end if

}//end if

}//end else

} while (!empty(*Maze_stack));

return 0;

}

/*打印迷宫*/

void printMaze()

{

int i, j;

for (i = 0; i < ROW+2; ++i)

{

for (j = 0; j < COL+2; ++j){

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

}

printf("\n");

}

}

int main()

{

//stack_test();

position start = { 1, 1 };/*迷宫入口*/

position end = { 10, 10 };/*迷宫出口*/

Stack_pNode maze_stack;/*声明一个栈,一会儿用来存放在迷宫中走过的位

置*/

InitStack(&maze_stack);/*初始化栈*/

if (find_path(&maze_stack, start, end)){

reverse(&maze_stack);/*因为栈中存放的是倒置的信息,须要将栈

倒置*/

print(maze_stack);/*打印带有走过的步数信息的迷宫地图*/

}

else{

printf("Has no way to out of the maze.\n");

}

printMaze();

return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值