




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
一、實(shí)驗(yàn)內(nèi)容
3、迷宮問(wèn)題。假設(shè)迷宮由m行n列構(gòu)成,有一個(gè)出口和一個(gè)入口,入口坐標(biāo)為(1,1),出口
坐標(biāo)為(m,n),試設(shè)計(jì)并驗(yàn)證以下算法:找出一條從入口通往出口的途徑,或報(bào)告一個(gè)“無(wú)
法通過(guò)”的信息。
(1)用C語(yǔ)言實(shí)現(xiàn)順序存儲(chǔ)隊(duì)列上的基本操作,然后運(yùn)用該隊(duì)列的基本操作找出迷宮
的一條最短途徑。
(2)設(shè)計(jì)一個(gè)二維數(shù)組MAZE[m+2][n+2]表達(dá)迷宮,數(shù)組元素為0表達(dá)該位置可以
通過(guò),數(shù)組元素為1表達(dá)該位置不可以通行。MAZE[1][1],MAZE[m][n]分別為迷宮的
入口和出口。
(3)輸入迷宮的大小m行和n歹!I,動(dòng)態(tài)生成二維數(shù)組;由隨機(jī)數(shù)產(chǎn)生0或1,建立迷宮,
注意m*n的迷宮需要進(jìn)行擴(kuò)展,擴(kuò)展部分的元素設(shè)立為1,相稱于在迷宮周邊布上一圈不準(zhǔn)通
過(guò)的墻。
(4)規(guī)定輸出模擬迷宮的二維數(shù)組;若存在最短途徑,則有出口回溯到入口(出隊(duì)列并運(yùn)
用棧實(shí)現(xiàn)),再打印從入口到出口的這條途徑,例如(1,1),............(i,j)...........(m,n);
若沒(méi)有途徑,則打印“Nopath”。
(5)迷宮的任一位置(i,j)上均有八個(gè)可移動(dòng)的方向,用二維數(shù)組Direction存放八個(gè)
方向的位置偏移量。
Direction[8][2]={{0,1},{1,1},{0,-1},{-1,-1},{1{-1,0},
{」/}};
(6)為避免出現(xiàn)原地踏步的情況需要標(biāo)志已經(jīng)通過(guò)的位置,采用一個(gè)標(biāo)志數(shù)組MAR
K[m+2][n+2],初值均為0,在尋找途徑的過(guò)程中,若通過(guò)了位置(i,j),則將MARK[i]
lj]置為1。
(7)為了記錄查找過(guò)程中到達(dá)位置(i,j)及初次到達(dá)(i,j)的前一位置(i_pre,j_pre),
需要記住前一位置(i_pre,j_pre)在隊(duì)列中的序號(hào)pre,即隊(duì)列中數(shù)據(jù)元素應(yīng)當(dāng)是一個(gè)三
元組(i,j,pre),
(8)搜索過(guò)程簡(jiǎn)樸下:將入口MAZE"][1]作為第一個(gè)出發(fā)點(diǎn),依次在八個(gè)方向上
搜索可通行的位置,將可通行位置(i,j,pre)入隊(duì),形成第一層新的出發(fā)點(diǎn),然后依次出隊(duì),即
對(duì)第一層中各個(gè)位置分別搜索它所在八個(gè)方向上的可通行位置,形成第二層新的出發(fā)點(diǎn),…,
如此進(jìn)行下去,直至達(dá)成出口MAZE[m]ln]或者迷宮所有位置都搜索完畢為止。
二、實(shí)驗(yàn)過(guò)程及結(jié)果
一、需求分析
1、用棧的基本操作完畢迷宮問(wèn)題的求解,其中棧的基本操作作為一個(gè)獨(dú)立的模塊存在。
2、以二維數(shù)組M[m+2][n+2]表達(dá)迷宮,MEi][j]表達(dá)迷宮中相應(yīng)(i,j)位置的
通行狀態(tài)(0:表達(dá)可以通行,1:表達(dá)有墻,不可通行),完畢迷宮的抽象數(shù)據(jù)類型,涉及出
口、入口位置等。
3、用戶從屏幕上輸入迷宮,從鍵盤輸入迷宮的大小,即迷宮的長(zhǎng)和寬(由于控制臺(tái)大
小限制,輸入的長(zhǎng)寬需在50以下),完畢相應(yīng)迷宮的初始化。根據(jù)鍵盤輸入的迷宮規(guī)格隨機(jī)
生成大小相同的迷宮,產(chǎn)生方塊的地方為墻,無(wú)方塊的地方可通過(guò),如下例所示:
如下所示:
■習(xí)軟件、MicrosoftVisualStudio\Debug^3^Ht5i^?.e
PleaseinputthelengthandwidthoftheMAZE:
length<0<length<=50>:12
width<0<width<=50>:12
迷宮入口:H,i]一用#表示—
迷宮出口:112,121一同*表小
4、程序完畢對(duì)迷宮途徑的搜索,為了更好地顯示出求解結(jié)果,假如存在途徑,則以長(zhǎng)方形
形式將迷宮打印出來(lái),而不是只按步輸出坐標(biāo),也便于檢查途徑的對(duì)的性,用特定符號(hào)標(biāo)出
迷宮的物理狀態(tài),其中字符表達(dá)出口和入口,標(biāo)記出可行的途徑;假如程序完畢
搜索后沒(méi)有找到通路,則提醒用戶“NoPath!”。如圖所示:
5、程序執(zhí)行的命令:
⑴創(chuàng)建初始化迷宮;
⑵搜索迷宮;
⑶輸出搜索到的最短途徑。
二、概要設(shè)計(jì)
(按照題目規(guī)定應(yīng)當(dāng)用隊(duì)列實(shí)現(xiàn)途徑的存儲(chǔ),但操作過(guò)程中碰到很多困難未能解決,故選擇棧
的操作來(lái)實(shí)現(xiàn)途徑的存儲(chǔ))
1、迷宮的抽象數(shù)據(jù)類型定義:
ADTMaze{
數(shù)據(jù)對(duì)象:D:={aij,Start,end卜20<=aij<20,Start,ende{(i,j)|0WiWm+2,0
WjWn+2,m,n20}}
數(shù)據(jù)關(guān)系:R={length,width}
?length={<ai_1j,aij>|ai-1,aijGDi=1,,,,,m+2,j=1,,,,,n+2}
owidth={<aij-l,aij>|aijaij-1eD)
基本操作:
SetMaze(&M)
初始條件:M已經(jīng)定義,M的下屬單元二維數(shù)組M.Maze[row+2][d+2]已存在,
M.start,M.end也已作為下屬存儲(chǔ)單元存在
操作結(jié)果:構(gòu)成數(shù)據(jù)迷宮,用數(shù)值標(biāo)記迷宮的物理狀態(tài),以0表達(dá)通路,以1表達(dá)障礙,
由終端讀取迷宮空間大小,各點(diǎn)處的具體物理狀態(tài)及Start和End點(diǎn)位置,完畢迷宮構(gòu)建
Pass(M,CurPos)
初始條件:已知目前迷宮狀態(tài)及當(dāng)前位置
操作結(jié)果:完畢相應(yīng)的搜索任務(wù),假如可行,則返回1
NextPos(CurPos,directionr)
操作結(jié)果:返回CurPOS位置在方向direction上的下一位置
SameSeat(Path,row,col)
操作結(jié)果:若(row,col)位置是途徑Path中的一個(gè)點(diǎn),則返回TRUE
PrintMaze(M)
初始條件:迷宮M已存在
操作結(jié)果:輸出字符標(biāo)示的迷宮
MazePath(M,&Path)
初始條件:迷宮M已存在
操作結(jié)果:搜索迷宮,用palh返回搜索所得途徑。如不存在,返回0
PrintPath(M,Path)
初始條件:迷宮M已存在
操作結(jié)果:迷宮M存在可行途徑則將迷宮M及相應(yīng)最短途徑一起打印輸出
}ADTMAZE;
3.本程序模塊結(jié)構(gòu)
(1)主函數(shù)模塊
voidmain(){
初始化迷宮和棧;
創(chuàng)建迷宮:
輸出迷宮;
搜索途徑;
輸出途徑;
)
⑵棧模塊一一實(shí)現(xiàn)棧抽象數(shù)據(jù)類型;
⑶迷宮模塊一一實(shí)現(xiàn)迷宮抽象數(shù)據(jù)類型;
各模塊之間的調(diào)用關(guān)系如下:
主程序模塊
迷宮模塊
棧模塊
三、具體設(shè)計(jì)
1、基本數(shù)據(jù)類型操作
⑴棧模塊
①typedefstruct{
intorder;
ePositionseat;
“ntdirection;
}SEIemiype;//步數(shù)、方向及位置
//棧定義
②typedefstructlnode{
SElemType*base;
SElemType*top;〃設(shè)兩指針便于判斷棧是否為空
intstacksize;//棧當(dāng)前可使用的最大容量
}SqStack;
③參數(shù)設(shè)立:
#defineSTACKJNIT_SIZE100
#defineSTACKINCRENT10
//.....--基本操作的算法描述——一-------一一
StatusInitStack(SqStack&s){//構(gòu)造一個(gè)空棧
S.base=(SelemType)mal1oc(STACKJNIT_SIZE*SizeOf(SelemType));
if(!S上ase)exit(OVERLOW);//存儲(chǔ)分派失敗
S.top=S.base;
S.stacksize=STACKJNIT_SIZE;
returnok;
)
StatusStackEmpty(Sqstack&S){//若S為空返回TRUE,否則
返回FALSE
returnS.base==S,top;
)
StatusGetTop(SqStack&S,Se1emtype&e){
//棧不空,用e返回s的棧頂元素及OK,否則返回ERROR
if(S.top==S.base)returnERROR;
e=*(S.top-1);
returnok;
StatusPush(Sqstack&S,SelemType&e){//插入元素e為新的棧頂元
素
if(S.top-S.base>=S.stacksize){//棧滿追加存儲(chǔ)空間
S.base=(SelemType)realloc(S.base,(S.stacksize+STACK
ICREMENT)Sizeof(Selemtype));
if(!S.base)exit(OVERFLOW)〃存儲(chǔ)分派失敗
S.top=S.base+S.stacksize;//擬定新的棧頂指針
S.stacksize+=STACKINCREMENT;//已分派空間增長(zhǎng)
)
*S.top++=*e;
returnok;
)
StatusPop(Sqstack&s,Se1emType&e){
//若棧不變,則刪除棧頂元素,用e返回其值及ok,否則false
if(S.top=o=S.base)
returnERROR;
*e=*--S.top;//頂指針減小,用e返回其數(shù)據(jù)
returnok;
)
⑵迷宮模塊:
①迷宮的數(shù)據(jù)類型
#defineMAXLENGTH50//迷宮的最大長(zhǎng)度
#defineMAXWIDTH50//屏幕寬度,迷宮的最大寬度
〃元素類型
typedefintStatus;
typedefstruct{
introw;
intco1;
}Position;。//位置坐標(biāo)
〃迷宮定義
typedefintElemType;
typedefstructMAZE{
ElemTypeMaze[MAXLENGTH][MAXWIDTH];。//迷宮的物理狀
態(tài)描述
intlength,width;//迷宮的大小
oPositionstart,end;//開(kāi)始與結(jié)束位置與棧的單元類型相同
JMAZE;//“迷宮”型數(shù)據(jù)
②迷宮模塊中的基本操作
Statussemaze(MAZE&M){
Printf(aP1easeinputthelengthandwidthoftheMAZE");
sanf(arlength,width”);
for(k=0;k<width+2;k++)?
wM->Maze[0][k]=1;
。for(j=0;j<length+2;j++)
8M->Maze|jj[0
for(j=0;j<1ength+2;j++)
。M一〉Maze皿width+1]=1;
for(k=0;kVwidth+2;k++)
。oM->Maze[length+l][k]=1;。//設(shè)立迷宮圍墻
4or(j=1;j<=length;j++)
。(
for(k=1;k<=width;k++)
oM->Maze[j][k]=rand()%2;。//隨機(jī)生成迷宮
}
M->1ength=length;
M—>width=width;
<>M->start.row=1;
<>M->start.col=1;
M->end.row=M->1ength;
M—>end.col=M->width;。
<>M->Maze[M—>start.row][M->start.co1]=M->Maze[M—>end.row][M->end.
col]=0;〃入口和出口設(shè)立*/
)
voidPrintMaze(MAZEM){〃打印出迷宮,涉及邊界
prinlf("迷宮入口:[l,l]一用#表達(dá)\n”);
printf("迷宮出口:[%d,%d1用#表達(dá)\n”,M.1ength,M.width);
?>for(row=0;row<M.length+2;row++){
ofor(col=0;co1<M.width+2;co1++){
if((row==1&&col==1)||(row==M.length&&col==M.width))
oprintff'#入口和出口用#表達(dá)
8?e1se
u
eMprintf(%c0,M.Maze[row][co1]);
°)
printf(H\nM);
}//用字符型打印輸出(i,j)狀態(tài)
)
StatusPass(MAZEM,PositionCurPos){
//判斷迷宮中當(dāng)前位置CurPos上能否通過(guò)
//假如通過(guò)返回1
if(M.Maze[CurPos.rowJ[CurPos.col]==0)
return1;〃假如當(dāng)前位置是可以通過(guò),返回1
e1sereturn0;//其它情況返回0
)
PositionNextPos(PositionCurPos,intdirection){
〃返回當(dāng)前位置在direction方向上的下一位置
ReturnPos.row=CurPos.row+Directionfdirection-1][0];
ReturnPos.col=CurPos.co1+Direction[direction—1][1];
returnReturnPos;
)
StatusSameSeat(SqStackPath,introw,intcol){
//位置(row,col)在途徑中時(shí)返回TRUE
owhi1e(p<Path.top){
◎if(Path.base[num].seat.row==row&&Path.base[num].seat.col
==co1)//途徑某一步所在的位置
^returnTRUE;。
gnum++;
p++;
6returnFALSE;
)
StatusMazePath(MAZEM,SqStack*S){
。//若迷宮maze中從入口start到出口end的通道,則求得一條存放在棧中
//(從棧底到棧頂),并返回SUCCESS;否則返回FAIL
curpos=M.start;//設(shè)定”當(dāng)前位置“為“入口位置”
curstep=l;//探索第一步
〃第一次查找途徑,設(shè)立5個(gè)方向(不遠(yuǎn)離!終點(diǎn)的五個(gè)方向),若找到則返回
SUCCESS
討o{
oif(Pass(M,curpos)){//當(dāng)前位置可通過(guò),即是未曾走到過(guò)的通道塊
。M.Maze[curpos.row][curpos.col]-,;//留下足跡
。e.direction=1;
。e.order=curstep;
e.seat=curpos;
。Push(S,&e);//加入途徑
if(curpos.row==M.end.row&&curpos.co1==M.end.col){
。//到達(dá)終點(diǎn)(出口)
。returnSUCCESS;
0}
curpos=NextPos(curpos,l);//下一位置在當(dāng)前位置的
右下方
curstep++;//探索下一步
}
。else{〃當(dāng)前位置不能通過(guò)
。。if(!StackEmpty(S)){
。Pop(S,&e);
oowhile(e.direction==5&&!StackEmpty(S)){
。M.Maze[curpos.row][curpos.col]-';〃標(biāo)記不能通過(guò)
。。Pop(S,&e);//留下不能通過(guò)的標(biāo)記,并退回一步
go}//while
if(e.direction<5){
ge.direction++;
。。GetTop(S,&te);
川。if(e.direction==5&&te.direction==2){
8。Pop(S,&e);
e.direction++;
0)
。。Push(S,&e);//換下一個(gè)方向探索
。curpos=NextPos(e.seat,e.direction);//當(dāng)前位置設(shè)為新
方向的相鄰塊
。。}//if
。}//if
}//eIse
}while(!StackEmpty(S));
curpos=M.start;//設(shè)定”當(dāng)前位置"為“入口位置”
照urstep=1;〃探索第一步
//假如第一次查找無(wú)結(jié)果則再進(jìn)行一次八個(gè)方向的查找,檢查是否存在第一次
查找不到的特殊情況
0do{
if(Pass(M,curpos)){//當(dāng)前位置可通過(guò),即是未曾走到過(guò)的通道塊
M.MazeLcurpos.row]Lcurpos.co1]=,';//留下足跡
ge.direction=1;
oe.order=curstep;
0。e.seat=curpos;
dPush(S,&e);//加入途徑
°if(curpos.row==M.end.row&&curpos.col==M.end.co1){
e//到達(dá)終點(diǎn)(出口)
//PrintPath(maze,S);。//輸出途徑
returnSUCCESS;
°}
bcurpos=NextPos(curposj);//下一位置是當(dāng)前位置的東
鄰
curstep++;//探索下一步
)
0else{//當(dāng)前位置不能通過(guò)
if(!StackEmpty(S)){
Pop(S,&e);
。whi1e(e.direction==8&&!StackEmpty(S)){
。M.Maze[curpos.row][curpos.col]-';〃標(biāo)記不能通過(guò)
6Pop(S,&e);//留下不能通過(guò)的標(biāo)記,并退回一步
6。}//while
。if(e.direction<8){
°e.direction++;
egGetTop(S,&te);
oo。if(e.direction==4&&te.direction==2){
00Pop(S,&e);
。e.direction++;
d0I
Push(S,&e);//換下一個(gè)方向探索
。curpos=NextPos(e.seat,e.direction);//當(dāng)前位置設(shè)為新方向
的相鄰塊
。。。}//if
。}//if
}//else
}while(!StackEmpty(S));
6returnFAIL;
}//MazePath
voidPrintPath(MAZEM,SqStackPath){//將迷宮及途徑一起打印
if(StackEmpty(&Path)){
叩rinlf(”NoPath!\n");//途徑棧為空,則提醒無(wú)途徑
。exit(OVERFLOW);
)
printf(H\nThePath:\nn);
for(row=0;row<M.1ength+2;row++){
for(co1=0;col<M.width+2;col++){
?if(SanieSeat(Path,row,co1)){
。if((row==l&&col==1)||(row==M.length&&col==M.width))
。sprintf("#");
oelse
000叩rintf(">");
00num++;
叩++;
Odd|
。吒1se
。。printf(n%c",M.Maze[row][col]);
)
oprintf("\n");
)
)
⑶主函數(shù)算法:
voidmain(){
oMAZEM;
qStackpath;
InitStack(&path);
<>SetMaze(&M);
?PrintMaze(M);
?>MazePath(M,&path);
PrintPath(M,path);
)
2.函數(shù)的調(diào)用關(guān)系反映了本演示程序的層次結(jié)構(gòu)
main1
丁佐桂港方迷宮德海
InitStackMazePathPrintPathPrintMazePassSetMaze
SameSeatNextPos
PushGetTopPop
StackEmpty
四、調(diào)試分析
1、開(kāi)始沒(méi)有將start.end設(shè)立為MAZE型數(shù)據(jù)的下屬單元,使得各個(gè)迷
宮操作的函數(shù)參數(shù)十分散雜,調(diào)試時(shí)各參數(shù)關(guān)系不易把握。
2、另行設(shè)立PrintPath函數(shù),使得終端輸出更加和諧,并巧妙地將迷宮以特殊、明朗
的字符輸出,效果更好。
3、開(kāi)始出棧入棧的條件沒(méi)有控制好,導(dǎo)致輸出時(shí)不是完整途徑,甚至犯錯(cuò)。
4、選擇方向時(shí)有一定策略,開(kāi)始選擇時(shí)按照順時(shí)針依次讀取方向,發(fā)現(xiàn)太耗時(shí)且效果不
好,容易出現(xiàn)不必要的彎折走法,后來(lái)通過(guò)控制方向順序,即第一方向?yàn)闁|南方,然后再
東方、南方…,選取越靠近出口的方向?yàn)閮?yōu)先方向,由于這樣的話搜索途徑時(shí)自然會(huì)本著
途徑最短的原則向出口處行進(jìn),那么找到的途徑自然是最短途徑(之一)。
5、由于八個(gè)方向的特殊性,根據(jù)方向的順序及索途徑時(shí)仍會(huì)出現(xiàn)多走的情況,比如先往
東再往西南,其實(shí)是可以直接往南的,因此為了避免這種情況,在入棧時(shí)還要先進(jìn)行這
種情況的判斷,如是這種情況則出棧將前一位置方向改變?cè)偃霔!?/p>
6、為了便于找到最短途徑,起初只使用了靠近出口處的五個(gè)方向,但是發(fā)現(xiàn)有特殊情況
存在時(shí)由于不能想遠(yuǎn)離出口的方向行進(jìn)而找不到途徑,因此在搜索途徑時(shí)進(jìn)行了兩次搜
索,第一次使用五個(gè)靠進(jìn)出口的方向搜索,找到途徑時(shí)則返回SUCCESS,若未搜索
到則再進(jìn)行一次八個(gè)方向的搜索,即為了防止漏掉特殊情況,找屆時(shí)則返回SUCCESS,
由于第一搜索無(wú)結(jié)果若第二次搜索到途徑也只能是特殊情況,故也應(yīng)當(dāng)是最短途徑(之
一)。
7、最大的問(wèn)題是并沒(méi)有按照題目規(guī)定來(lái)做,由于題目中規(guī)定用隊(duì)列來(lái)存儲(chǔ)途徑,通過(guò)實(shí)驗(yàn)
發(fā)現(xiàn)有很多問(wèn)題難以解決,故選擇了只用棧的方法來(lái)實(shí)現(xiàn)。
五、用戶說(shuō)明
1.本程序的運(yùn)營(yíng)環(huán)境為windows7(64位)操作系統(tǒng),執(zhí)行文獻(xiàn)為數(shù)據(jù)結(jié)構(gòu)迷宮.e
xe;
2.進(jìn)入演示程序后,即顯示對(duì)話形式的提醒操作過(guò)程,
1、提出輸入迷宮的大小
2、按enter鍵輸出隨機(jī)生成的迷宮
3、按enter鍵開(kāi)始搜索途徑
搜索結(jié)果:
ThePath:輸出迷宮及途徑或者輸出NoPath!
3.提醒輸入迷宮大小后,用戶輸入所要解決迷宮的長(zhǎng)r。w,寬col;
4.提醒輸入迷宮后,用戶將迷宮輸入,0代表可行,1代表障礙;
5.按任意鍵開(kāi)始后,程序自動(dòng)進(jìn)行對(duì)所建迷宮的搜索,并將搜索結(jié)果;
6.按任意鍵退出程序。
六、測(cè)試結(jié)果
1、無(wú)途徑:
■習(xí)軟件'MicrosoftVisualStudio\Debug\SQ^§^迷宮.
PleaseinputthelengthandwidthoftheMAZE:
length<0<length<=50>:12
width<0<width<=50>:12
修宮入口:H,l]一用Jt表示—
族宮出口:H2,12]一同年小
@@@@@@@@@@@@@@
⑹??
n?00
QQ?
Q
@?
??
Q□Q
Q???
3Q?
?
jQ□□□
?0
3Q?
??0
30
?Q?0
QQ?QQ0
QQQ
?????0
@@@@
Path?
Pressanytocontinue
2、找到最短途徑:
PleaseinputthelengthandviidthoftheMAZE:
[length<0<length<=50>:15
^idth<0<width<=50>:16
圈宮入口:tia]一用*表示—
修宮出口:115,16]一用建不
@@@◎
Q?QQ
??00Q????
Q?????00?0
0??00?
??????0000000???Q
13
?000??
Q
>?
XK
Xz◎◎
Q??Q
◎
?????
0Q◎
?Q?
◎
??0
QQ?Q◎
00???
QQQ◎
?Q?
0?Q
Q?0
?0???
Q>
Q?Q?
>
QQQ????
>@
0??
n
Q?Q?@Q????Q
?Q
ay
nytocontinue
七、附錄(源代碼及注釋)
#include"time.h"
#includestdio.h"
#include"stdlib.h',
#inc1udeuconio.h"
#defineNULL0
#defineTRUE1
#defineFALSE0
#defineSUCCESS1
#defineFAIL0
#defineOK1
#defineERROR0
#defineOVERFLOW-1
#defineINFEASIBLE-2
#defineMAXLENGTH50
#defineMAXWIDTH50
#defineSTACK_INIT_SIZE100
#defineSTACKINCRENT10
//元素類型
typedefintStatus;
typedefstruct{
ointrow;
intcol;
}Position;〃位置坐標(biāo)
typedefstruct{
?intorder;
oPositionseat;
intdirection;
}SElemType;//步數(shù)、方向及位置
〃棧定義
typedefstructInode{
SElemType*base;
SElemType*top;//設(shè)兩指針便于判斷棧是否為空
intstacksize;〃棧當(dāng)前可使用的最大容量
}SqStack;
//迷宮定義
typedefintElemType;
typedefstructMAZE{
E1emTypeMaze[MAXLENGTH][MAXWIDTH];
ointlength,width;
0Positionstart,end;
}MAZE;〃迷宮大小及出入口位置
//棧操作函數(shù)聲明
StatusInitStack(SqStack*S);//初始化
StatusStackEmpty(SqStack*S);//判空
StatusGetTop(SqStack*s,SElemType*e);〃取棧頂元素
StatusPush(SqStack*S,SElemType*e);//入棧
StatusPop(SqStack*s,SE1emType*e);//出棧
//迷宮操作函數(shù)說(shuō)明
voidSetMaze(MAZE*M);。/*設(shè)立迷宮,隨機(jī)生成*/
voidPrintMaze(MAZEM);。/*輸出迷宮*/
StatusPass(MAZEM,PositionCurPos);〃判斷當(dāng)前位置是否可通
PositionNextPos(PositionCurPos,intdirectionr);〃下一位置
StatusSameSeat(SqStackPath,introw,intcol);//找到迷宮中可行途徑的各個(gè)位置
StatusMazePath(MAZEM,SqStack*Path);//搜索迷宮途徑
voidPrintPath(MAZEM,SqStackPath);//若迷宮M存在可行途徑則將該途徑在迷宮
中輸出
//主函數(shù)
voidmain(){
oMAZEM;
?SqStackpath;
“nitStack(&path);
oSetMaze(&M);
PrintMaze(M);
0MazePath(M,&path);
3PrintPath(M,path);
)
〃迷宮操作
voidSetMaze(MAZE*M){
“nt1ength,width,j,k;
oprintf("Pleaseinputthe1engthandwidthoftheMAZE:\nlength
(0<length<=50):");
?scanf(u%d”,&1ength);
叩rintf("width(0<width<=50):H);
oscanf(0%d",&width);
srand((unsigned)time(NULL));
?for(k=0;k<width+2;k++)。
M->Maze[OJ[k]=1;
。for(j=0;j<1ength+2;j++)
^M->Maze[j][0]=l;
?for(j=0;j<length+2;j++)
。。M->Maze[j][width+l]=1;
for(k=0;k<width+2;k++)
。oM—>Maze[1ength+1][k]=1;“/設(shè)立迷宮圍墻
6for(j=1;j<=length;j++)
°{
。for(k=l;k<=width;k++)
M->Maze[j][k]=rand()%2;?!S機(jī)生成迷宮
)
M—>length=length;
<>M->width=width;
oM->start,row=1;
◎M->start.col=l;
M->end.row=M->length;
oM->end.co1=M->width;
M->Maze[M->start,row][M->start.co1]=M—>Maze[M->end.row][M—>en
d.col]=0;//入口和出口設(shè)立*/
)
voidPrintMaze(MAZEM){
introw,col;
叩rintf("迷宮入口:[1,1]——用#表達(dá)\n");
printf("迷宮出口:1%4%打一-用#表達(dá)\廣\4.怕1^111,\4.width);
ofor(row=0;row<M.length+2;row++){
。for(col=0;col<M.width+2;co1++){
。?if((row==l&&col==l)||(row==M.1ength&&col==M.width))
printf("〃入口和出口用#表達(dá)
。。吒Ise
。3printf(u%cM.Maze[row][col]);
0)
?printf(M\nn);
°)
)
StatusPass(MAZEM,PositionCurPos){
if(M.Maze[CurPos.row][CurPos.co1]==0)
return1;//假如當(dāng)前位置是可以通過(guò),返回1
eIsereturn0;//其它情況返回0
)
PositionNextPos(PositionCurPos,intdirection){
PositionReturnPos;
疝itDirection[8][2]={{1,1},{0,1},{1,O},{-1,1},{1,-1},{0,-1},{-1,0},{-1,-
1}};//按一定順序依次設(shè)立八個(gè)方向
oReturnPos.row=CurPos.row+Direction[direction-l][0];
RetumPos.co1=CurPos.col+Direction[direction-1][1];
returnReturnPos;
)
StatusSameSeat(SqStackPath,introw,intco1){
?SElemType*p=Path.base;
intnum=O;
while(p<Path.top){
ooif(Path.base[num].seat.row==row&&Path.base[num].seat.col==col)//
徑某一步所在的位置
oreturnTRUE;。
num++;
0p++;
)
returnFALSE;
)
StatusMazePath(MAZEM,SqStack*Path){
。//若迷宮maze中從入口start到出口end的通道,則求得一條存放在棧中
“/(從棧底到棧頂),并返回SUCCESS;否則返回FAIL
Positioncurpos;
?intcurstep;
oSElemTypee,te;
ocurpos=M.start;//設(shè)定”當(dāng)前位置“為“入口位置”
◎curstep=l;//探索第一步
?!ǖ谝淮尾檎彝緩?,設(shè)立5個(gè)方向(不遠(yuǎn)離!終點(diǎn)的五個(gè)方向),若找到則返回SUCCESS
do{
if(Pass(M,curpos)){//當(dāng)前位置可通過(guò),即是未曾走到過(guò)的通道塊
M.Maze[curpos.row][curpos.col]='';//留下足跡
。e.direction=1;
Qe.order=curstep;
e.seat=curpos;
。。Push(S,&e);//加入途徑
if(curpos.row==M.end.row&&curpos.co1==M.end.col){
//到達(dá)終點(diǎn)(出口)
returnSUCCESS;
0)
“curpos=NextPos(curpos,1);//下一位置在當(dāng)前位置的右下方
curstep++;//探索下一步
0)
else{//當(dāng)前位置不能通過(guò)
if(!StackEmpty(S)){
Pop(S,&e);
owhile(e.direction==5&&!StackEmpty(S)){
。M.Maze[curpos.row][curpos.co1]='標(biāo)記不能通過(guò)
。Pop(S,&e);//留下不能通過(guò)的標(biāo)記,并退回一步
。。。}//while
。。。if(e.direction<5){
se.direction++;
ggGetTop(S,&te);
。if(e.direction==5&&te.direction==2){
。?ePop(S,&e);
。。e.direction++;
000|
6ePush(S,&e);〃換下一個(gè)方向探索
curpos=NextPos(e.seat,e.direction);//當(dāng)前位置設(shè)為新方向的相
鄰塊
}//if
。}//if
。}//else
“while(!StackEmpty(S));
curpos=M.start;//設(shè)定”當(dāng)前位置"為“入口位置"
ocurstep=l;//探索第一步
?!偃绲谝淮尾檎覠o(wú)結(jié)果則再進(jìn)行一次八個(gè)方向的查找,檢查是否存在第一次查找不到的特
殊情況
0do{
if(Pass(M,curpos)){//當(dāng)前位置可通過(guò),即是未曾走到過(guò)的通道塊
。。M.Maze[curpos.row][curpos.col]=,*;//留下足跡
e.direction=1;
。e.order=curstep;
e.seat=curpos;
。Push(S,&e);//加入途徑
。if(curpos.row==M.end.row&&curpos.co1==M.end.co1){
//到達(dá)終點(diǎn)(出口)
川//PrintPath(maze,S);//輸出途徑
。。。returnSUCCESS;
3)
3curpos=NextPos(curpos,1);//下一位置是當(dāng)前位置的東鄰
curstep++;/
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024-2025新教材高中物理課時(shí)素養(yǎng)評(píng)價(jià)十一牛頓第三定律含解析新人教版必修1
- 第三單元 第15課《互聯(lián)網(wǎng)實(shí)驗(yàn)齊發(fā)現(xiàn)》教學(xué)設(shè)計(jì) 2024-2025學(xué)年人教版(2024)初中信息科技七年級(jí)上冊(cè)
- 第1課《計(jì)算機(jī)網(wǎng)絡(luò)》教學(xué)設(shè)計(jì) 2024-2025學(xué)年浙教版(2023)初中信息技術(shù)七年級(jí)上冊(cè)
- 高中信息技術(shù)選修5教學(xué)設(shè)計(jì)-1.2.6 其他應(yīng)用-教科版
- 第六單元 百分?jǐn)?shù)(一)(教學(xué)設(shè)計(jì))-2024-2025學(xué)年數(shù)學(xué)人教版六年級(jí)上冊(cè)
- 粵教版(2019)必修一 4.4.1for循環(huán)的應(yīng)用 教學(xué)設(shè)計(jì)
- 10《愛(ài)心的傳遞者》教學(xué)設(shè)計(jì)-2024-2025學(xué)年道德與法治三年級(jí)下冊(cè)統(tǒng)編版
- 23 設(shè)計(jì)水火箭 教學(xué)設(shè)計(jì)-2023-2024學(xué)年科學(xué)六年級(jí)上冊(cè)青島版
- 第10課 《老人與?!方虒W(xué)設(shè)計(jì)-2024-2025學(xué)年高二語(yǔ)文上學(xué)期同步教學(xué)教學(xué)設(shè)計(jì)+教學(xué)設(shè)計(jì)(選擇性必修上冊(cè))
- 2025年薯類生產(chǎn)項(xiàng)目建議書(shū)
- 2024-2025學(xué)年山東省濰坊市高三上學(xué)期1月期末英語(yǔ)試題
- 2025-2030年中國(guó)青海省旅游行業(yè)市場(chǎng)現(xiàn)狀調(diào)查及發(fā)展趨向研判報(bào)告
- 人力資源部門2023年度招聘效果分析
- 八年級(jí)數(shù)學(xué)下冊(cè) 第1章 單元綜合測(cè)試卷(北師版 2025年春)
- 商業(yè)銀行的風(fēng)險(xiǎn)審計(jì)與內(nèi)部控制
- 2024項(xiàng)目管理人員安全培訓(xùn)考試題及參考答案AB卷
- 2025年安徽碳鑫科技有限公司招聘筆試參考題庫(kù)含答案解析
- 2025年寒假實(shí)踐特色作業(yè)設(shè)計(jì)模板
- 2024年福建漳州人才發(fā)展集團(tuán)有限公司招聘筆試參考題庫(kù)附帶答案詳解
- JTGT F20-2015 公路路面基層施工技術(shù)細(xì)則
- 小學(xué)數(shù)學(xué)計(jì)算練習(xí)-一年級(jí)上學(xué)期口算練習(xí)(600題打印版)
評(píng)論
0/150
提交評(píng)論