迷宫问题的CC算法实现讲解.docx

上传人:b****7 文档编号:23923916 上传时间:2023-05-22 格式:DOCX 页数:16 大小:21.23KB
下载 相关 举报
迷宫问题的CC算法实现讲解.docx_第1页
第1页 / 共16页
迷宫问题的CC算法实现讲解.docx_第2页
第2页 / 共16页
迷宫问题的CC算法实现讲解.docx_第3页
第3页 / 共16页
迷宫问题的CC算法实现讲解.docx_第4页
第4页 / 共16页
迷宫问题的CC算法实现讲解.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

迷宫问题的CC算法实现讲解.docx

《迷宫问题的CC算法实现讲解.docx》由会员分享,可在线阅读,更多相关《迷宫问题的CC算法实现讲解.docx(16页珍藏版)》请在冰豆网上搜索。

迷宫问题的CC算法实现讲解.docx

迷宫问题的CC算法实现讲解

基于栈的c语言迷宫问题与实现

1.问题描述

多年以来,迷宫问题一直是令人感兴趣的题目。

实验心理学家训练老鼠在迷宫中寻找食物。

许多神秘主义小说家也曾经把英国乡村花园迷宫作为谋杀现场。

于是,老鼠过迷宫问题就此产生,这是一个很有趣的计算机问题,主要利用“栈”是老鼠通过尝试的办法从入II穿过迷宫走到出口。

迷宫只有两个门,一个叫做入口,另一个叫做出口。

把一只老鼠从一个无顶盖的人盒子的入11处赶进迷宫。

迷宫中设置很多隔壁,对前进方向形成了多处障碍,在迷宫的唯一出11处放置了一块奶酪,吸引老鼠在迷宫中寻找通路以到达出II。

求解迷宫问题,即找出从入II到出口的路径。

一个迷宫可用上图所示方阵[ni,n]表示,0表示能通过,1表示不能通过。

现假设耗子从左上角[1,1]进入迷宫,编写算法,寻求一条从右下角[m,n]出去的路径。

下图是一个迷宫的示意图:

2.算法基本思想

迷宫求解问题是栈的一个典型应用。

基本算法思想是:

在某个点上,按照一定的顺序(在本程序中顺序为上、右、下、左)对周围的墙、路进行判断(在本程序中分别用1、0〉代替,若周围某个位置为0,则移动到该点上,再进行卞一次判断;若周围的位置都为1(即没有通路),则一步步原路返回并判断有无其他通路,然后再次进行相同的判断,直到走到终点为止,或者确认没有任何通路后终止程序。

要实现上述算法,需要用到栈的思想。

栈里面压的是走过的路径,若遇到死路,则将该位置(在栈的顶层)弹出,再进行下一次判断;若遇到通路,则将该位置压栈并进行卞一次判断。

如此反复循坏,直到程序结束。

此时,若迷宫有通路,则栈中存储的是迷宫通路坐标的倒序排列,再把所有坐标顺序打印后,即可得到正确的迷宫通路。

3.程序具体部分的说明

1.迷宫的生成

根据题目的要求,迷宫的人小是自定义输入的。

所以在程序中用malloc申请动态二维数组。

数组中的元素为随机生成的0、lo数组周闱一圈的元素全部定义为1,以表示边界。

2.栈的C语言实现

为了实现栈的功能,即清空、压栈、弹出、返回栈顶元素,在程序中编写了相应的函数。

MakeNULL清空栈

Push将横、纵坐标压栈

Topx返回栈顶存储的横坐标

Topy返回栈顶存储的纵坐标

Pop弹出栈顶元素

3.具体的判断算法

当位置坐标(程序中为XY)移到某一位置时,将这个位置的值赋值为1并压栈,以说明该点已经走过。

接着依次判断该点的上、右、下、左是否为0,若有一方为0,则移动到该位置上,进行下次判断;若为周I制位置全部是1,则将该点压栈后不断弹出,每次弹出时判断栈顶元素(即走过的路)周闱有无其他通路。

如果有的话,则选择该方向继续走下去;如果栈已经为空仍然没有找到出路,则迷宫没有出II程序结束。

当XY走到出II坐标时,程序判断部分结束。

栈里面存储的是每个走过的点的坐标,将这些横纵坐标分别存储在两个数组中,最后将数组中的坐标元素倒序输出,即得到了完整的路径。

4.程序源代码及注释

//Maze.cpp:

定义控制台应用程序的入口点。

//

★include"stdafx.h"

#incIude〈stdio.h>

#incIude〈string.h>

#include〈malloc.h>

#incIude

#incIude

typedefintElementtype;

struetnode

{

EIementtypeva11;

EIementtypeval2;

node*next;

};//定义结构体

typedefnode*MAZE;

voidMakeNulI(MAZE&S);

voidPush(EIementtypexrElementtypey,MAZES);voidPop(MAZES);

ElementtypeTopx(MAZES);

ElementtypeTopy(MAZES);//申明函数

int_tmain(intargc,_TCHAR*argv[])

{""

int**p,*q,*x1f*y1,i,j,k,n1,n2,ml,m2,I.w,max;irrtx,y;

irrta,b,c,d;

printf(”输入迷宫长度及宽度I和叭n“);

scanf("%d%d",&l,&w);

getchar();

n1=w+2;

n2=l+2;//为迷宫加上边界

max=n1*n2;

p=(int**)maIIoc(n1*sizeof(int));

for(i=0;i

p[i]=(int*)maIloc(n2*sizeof(int));//生成二维动态数组srand(time(NULL));

x1=(int*)maIloc(max*sizeof(int));//生成动态数组用于存储路径y1=(int*)maIloc(max*sizeof(int));//生成动态数组用于存储路径for(i=0;i

{

x1[i]二0;

for(i=0;i

{

y1[i]二0;

}//先将存储路径的数组元素全赋值为0

for(i=0;i

{

for(j=0;j

{

if(i==0||j=0)

{

p[i][j]二1;

}

elseif(i==n1-1||j==n2-1)

{

p[i][j]二1;

}

eIse

p[i][j]=rand()%2+0;

}

}〃生成二维10随机数组

p[1][1]=0;

p[n1-2][n2-2]=0;//定义迷宫的入口及出口

printfC生成的迷宫如下(代表墙0代表路):

\n");

for(i=0;i

for(j=0;j

printf("\n");

}〃打印迷宫

MAZES;

MakeNull(S);//清空栈

i=1;

j=1;

if(p[1][2]=1&&p⑵⑴=)

{

printf("Thereisnowayout");a

getchar();

return0;

}〃判断入口是否就是死路eIse

{

do

y二j;

Push(x,y,S);p[i][j]=;i=i-1;

}//判断能否向上走

elseif(p[i-1][j]=1&&p[i][j+1]==0)y二j;

Push(x,yrS);p[i][j]=;j二j+1;

}//判断能否向右走

elseif(p[i-1][j]==1&&p[i][j+1]=1&&p[i+1][j]==0)

y二j;

Push(x,y,S);k=Topx(S);p[i][j]=;i二i+1;

}〃判断能否向下走

elseif(p[i-1][j]==1&&p[i][j+1]=1&&p[i+1][j]==1&&p[i][j-1]==0)

y二j;

Push(x,y,S);p[i][j]=;J=J-1;

}〃判断能否向左走

elseif(p[i-1][j]==1&&p[i][j+1]==1&&p[i+1][j]=1&&p[i][j-1]==1)//判断如果为死路

{

p[i][j]=1;

x二i;

y二j;

Push(x,y,S);

for(;;)

{

Pop(S);//弹出栈顶元素

x=Topx(S);

y=Topy(S);//返回栈顶元素横纵坐标

if(p[x-1][y]==0)

{

i=x-1;

j二y;

p[i][j]二1;

X二i;

y二j;

Push(x,y,S);

break;

}

elseif(p[x-1][y]=1&&p[x][y+1]==0)

{

i二x;

j二y+1;

p[i][j]二1;

x二i;

y二j;

Push(x,y,S);

break;

}

elseif(p[x-1][y]=1&&p[x][y+1]==1&&p[x+1][y]==0)

{

i二x+1;

j二y;

p[i][j]二1;

x二i;

y二j;

Push(x,y,S);

break;

}

elseif(p[x-1][y]==1&&p[x][y+1]=1&&p[x+1][y]=1&&p[x][y-1]==0)

{

i二x;

j二yT;

p[i][j]二1;

x二i;

y二j;

Push(x,y,S);break;

}//判断弹出后栈顶元素周围有无通路

elseif(x~1&&y~1)

printf("Thereisnowayout”);getchar();

return0;

}//如果栈顶元素为入口则迷宫无出路}

1

}while(i!

=n1-2||j!

=n2-2);//循环截止条件

printf("Success!

\nTherouteis:

\n");for(i二0;;i++)

a二Topx(S);

b二Topy(S);

Pop(S);

x1[i]二a;

y1[i]二b;//将栈顶元素坐标存储在数组中

if(a~1&&b=1)

{

getchar();

break;

1

for(i二max-1;i>=0;)

{

if(x1[i]!

二0&&(x1[i]!

=x1[i-1]||y1[i]!

=y1[i-1]))

{

printf("<%d,%d>",x1[i],y1[i]);

i—;

1

elseif(x1[i]!

=0&&(x1[i]==x1[i-1]&&[订==y1[i-1]))

{

printf("<%d,%d>",x1[i],y1[i]);

i二i-2;

1

eIse

i一;

}〃倒序打印数组得到顺序出路坐标

printf(H<%d,%d>",n1-2,n2-2);〃打印出口坐标

getchar();

return0;

voidMakeNuII(MAZE&S)//清空栈的函数

S=newnode;

S->next二NULL;

}

voidPush(EIementtypex,Elementtypey,MAZES)//压栈函数{

MAZEstk;

stk=newnode;

stk->va11二x;

stk->va12二y;

stk->next二S->next;

S->next二stk;

}

voidPop(MAZES)//弹出函数

{

MAZEstk;

if(S->next)

{

stk=S->next;

S->next二stk->next;

deletestk;

}

ElementtypeTopx(MAZES)//返回横坐标函数

{

if(S->next)

return(S->next->va11);

eIse

returnNULL;

}

ElementtypeTopy(MAZES)//返回纵坐标函数

{

if(S->next)

return(S->next->va12);

eIse

returnNULL;

另一种方法实现的迷宫代码

#ifhdefMMIGONG.H

#defineMMIGONG_H

#defineMAX.SIZE100

#iiicludeusingnamespacestd;

stmctNode

{

liltX;

mty;intdi;

};

classStack

{

private:

mtrrow;

intccolin;

inttop;

intcount;

mtmuilenght;

Nodestack[MAX.SIZE];

Nodesstack[NIAX.SIZE];

public:

Stack();//初始化

//int**InsonMiGong();〃输入迷宫(即一个二维数组)voidFindPath(intab[][10]);〃找出迷宫的出路

};

Stack:

:

Stack()〃初始化

{

now=0;

ccohn=0;

top=-l;

count=l;

niuilenght=NIAX_SIZE;

}

/*int**Stack:

:

InsoilMiGong()〃输入迷宫(即一个二维数组){

intTow=]£olm=];

wliile(tnie)

{

cout«*'请输入迷宫的行数和列数:

”;

ciii»row»colin;

if(row<=01|colin<=0)

{

cout«H输入错误!

请重新输入:

n«endl;

rrox^row;

ccolm=colm;

continue;

}

else

{

rrox^row;

ccolm=colm;

break;

}

}

int*mg[];

cout«*'请输入迷宫矩阵(只有0和1两个数构成):

”;

foi(mti=0;i

fbr(mtj=0;j

cm»mg[i]Ij];returnmg;

}*/voidStack:

:

FindPath(intab[][10])〃找出迷宫的出路

{

inta.b.di.fiiid.k;

top++;stack[top].x=l;

stack[top].v=l;

stack[top].di=-l;

ab[l][l]=-l;

while(top>-l)

{

a=stack[top].x;

b=stack[top].v;

di=stack[top].di;

if(a==8&&b=8)

{

cout«count++«,,:

H«endl;

fdr(intk=0;k<=top;k++)

{coi】t«”(y

((k+l)%15))

cout«endl:

}

cout«endl;

if(top+1

{

for(k=0;k<=top;k++)sstack[k]=stack[k];

nunlenght=top+l;

}

ab[stack[top].x][stack[top].v]=0:

top—;a=stack[top].x;b=stack[top].y;di=stack[top].di;

}

find=0;

while(di<8&&!

find)

di++;switch(di)case0:

a=stack[top].x-1;b=stack[top].y;break;case1:

a=stack[top].x;b=stack[top].y+1;break;case2:

a=stack[top].x+l;b=stack[top].y;break;case3:

a=stack[top].x;b=stack[top].y-1;break:

}if(ab[a][b]==O)

find=l;

stack[top].di=di;top++;stack[top].x=a;stack[top].y=b;stack[top].di=-l;ab[a][b]=-l;

else

ab[stack[top].x][stack[top].v]=0:

}

cout«endl;

coutvv”走出迷宫最短的路径是:

"«eiidl;

cout«M其长度为:

H«niuilenght«endl;cout«M路径是:

H«endl;

for(k=O;k

cout«ll(,,«sstack[k].x«H;,«sstack[k].x«,,)n;if(k

cout«H->n;

if(!

((k+l)%10))

cout«endl;

}cout«endl;

#endif

#mcludeHMMIGONG.HM

Stackstack;intab[10][10]=

{1,1,1,1,1,1,1,1,1,1,},

{1,OA1,0,0,0,1,OJJ,

{1,0A1,0,0,0,1,OJJ,

{1,000,0,1,1,0,0,1,},

{1,0,1,1,1,000,0,1,},

{1,0,0,OJA0,0.0,1,},

{1,0,1,000,1,0,0,1,},

{1,0,1,1,1,0丄1,0,1,},

{1丄0,0,0,0,0,0,0丄},

{1,1,1,1,1,1,1,1,1,1,},

};

coutvv所有可以走出迷宫的路径有:

”《endl;

stack.FindPath(ab);

}

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 农林牧渔 > 水产渔业

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1