數(shù)據(jù)結(jié)構(gòu)課程設(shè)計-迷宮問題_第1頁
數(shù)據(jù)結(jié)構(gòu)課程設(shè)計-迷宮問題_第2頁
數(shù)據(jù)結(jié)構(gòu)課程設(shè)計-迷宮問題_第3頁
數(shù)據(jù)結(jié)構(gòu)課程設(shè)計-迷宮問題_第4頁
數(shù)據(jù)結(jié)構(gòu)課程設(shè)計-迷宮問題_第5頁
已閱讀5頁,還剩12頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、 目錄第一部分 需求分析第二部分 詳細(xì)設(shè)計第三部分 調(diào)試分析第四部分 用戶手冊第五部分 測試結(jié)果第六部分 附錄第七部分 參考文獻(xiàn)一、 需求分析 1、對于給定的一個迷宮,給出一個出口和入口,找一條從入口到出口的通路,并把這條通路顯示出來;如果沒有找到這樣的通路給出沒有這樣通路的信息。2、可以用一個m×n的長方陣表示迷宮,0和1分別表示迷宮中的通路和障礙。設(shè)計一個程序,對任意設(shè)定的迷宮,求出一條從入口到出口的通路,或得出沒有通路的結(jié)論。3、編寫一個求解迷宮的非遞歸程序。求得的通路以三元組(i,j,d)的形式輸出,其中:(i,j)指示迷宮中的一個坐標(biāo),d表示走到下一坐標(biāo)的方向。4、由于迷宮

2、是任意給定的,所以程序要能夠?qū)o定的迷宮生成對應(yīng)的矩陣表示,所以程序的輸入包括了矩陣的行數(shù)、列數(shù)、迷宮內(nèi)墻的個數(shù)、迷宮內(nèi)墻的坐標(biāo)、所求的通路的入口坐標(biāo)、出口坐標(biāo)。二、詳細(xì)設(shè)計 1、計算機(jī)解迷宮通常用的是“窮舉求解“方法,即從人口出發(fā),順著某一個方向進(jìn)行探索,若能走通,則繼續(xù)往前進(jìn);否則沿著原路退回,換一個方向繼續(xù)探索,直至出口位置,求得一條通路。假如所有可能的通路都探索到而未能到達(dá)出口,則所設(shè)定的迷宮沒有通路??梢远S數(shù)組存儲迷宮數(shù)據(jù),通常設(shè)定入口點的下標(biāo)為(1,1),出口點的下標(biāo)為(n,n)。為處理方便起見,可在迷宮的四周加一圈障礙。對于迷宮中任一位置,均可約定有東、南、西、北四個方向可通。

3、2、如果在某個位置上四個方向都走不通的話,就退回到前一個位置,換一個方向再試,如果這個位置已經(jīng)沒有方向可試了就再退一步,如果所有已經(jīng)走過的位置的四個方向都試探過了,一直退到起始點都沒有走通,那就說明這個迷宮根本不通。3、所謂"走不通"不單是指遇到"墻擋路",還有"已經(jīng)走過的路不能重復(fù)走第二次",它包括"曾經(jīng)走過而沒有走通的路"。顯然為了保證在任何位置上都能沿原路退回,需要用一個"后進(jìn)先出"的結(jié)構(gòu)即棧來保存從入口到當(dāng)前位置的路徑。并且在走出出口之后,棧中保存的正是一條從入口到出口的路徑。4、若當(dāng)前

4、位置“可通”,則納入“當(dāng)前路徑”,并繼續(xù)朝“下一位置”探索;若當(dāng)前位置“不可通”,則應(yīng)順著“來的方向”退回到“前一通道塊”,然后朝著除“來向”之外的其他方向繼續(xù)探索;若該通道塊的四周四個方塊均“不可通”,則應(yīng)從“當(dāng)前路徑”上刪除該通道塊。所謂“下一位置”指的是“當(dāng)前位置”四周四個方向(東、南、西、北)上相鄰的方塊。假設(shè)以棧S記錄“當(dāng)前路徑”,則棧頂中存放的是“當(dāng)前路徑上最后一個通道塊”。由此,“納入路徑”的操作即為“當(dāng)前位置入?!?;“從當(dāng)前路徑上刪除前一通道塊”的操作即為“出棧”。5、找通路的程序的關(guān)鍵部分可以表示如下:do 若當(dāng)前位置可通, 則將當(dāng)前位置插入棧頂; / 納入路徑 若該位置是出

5、口位置,則算法結(jié)束; / 此時棧中存放的是一條從入口位置到出口位置的路徑否則切換當(dāng)前位置的東鄰方塊為新的當(dāng)前位置; 否則若棧不空且棧頂位置尚有其他方向未被探索, 則設(shè)定新的當(dāng)前位置為: 沿順時針方向旋轉(zhuǎn)找到的棧頂位置的下一相鄰塊; 若棧不空但棧頂位置的四周均不可通, 則 刪去棧頂位置; / 從路徑中刪去該通道塊若棧不空,則重新測試新的棧頂位置, 直至找到一個可通的相鄰塊或出棧至棧空; while (棧不空); 6、程序中用的數(shù)據(jù)結(jié)構(gòu)解析: 程序中用了順序棧保存當(dāng)前找到的路徑,當(dāng)前位置不可通時,可以出棧,退回到前一個位置再繼續(xù)探索通路,棧的定義如下:struct SqStack SElemTyp

6、e *base; / 在棧構(gòu)造之前和銷毀之后,base的值為NULL SElemType *top; / 棧頂指針 int stacksize; / 當(dāng)前已分配的存儲空間,以元素為單位; / 順序棧 棧中元素的類型結(jié)構(gòu)程序中先定義了一個表示坐標(biāo)的類型結(jié)構(gòu):struct PosType / 迷宮坐標(biāo)位置類型 int x; / 行值 int y; / 列值 ;棧中元素的類型結(jié)構(gòu)如下:struct SElemType / 棧的元素類型 int ord; / 通道塊在路徑上的序號 PosType seat; / 通道塊在迷宮中的坐標(biāo)位置 int di; / 從此通道塊走向下一通道塊的方向(03表示東北

7、) ;7、主函數(shù)的流程圖輸出從起點到終點的坐標(biāo)顯示當(dāng)前含有通路的迷宮結(jié)構(gòu)輸出沒有這樣的通路輸入所求通路的起點終點坐標(biāo)顯示當(dāng)前的迷宮的結(jié)構(gòu)設(shè)置內(nèi)墻設(shè)置外墻輸入迷宮的行數(shù)列數(shù)(包括外墻) 三、 調(diào)試分析1、對于程序的設(shè)計由簡單到復(fù)雜,先設(shè)計一個整體的輪廓然后再慢慢的增加程序的功能,這樣能夠有效的減少錯誤,功能慢慢的增加,在前一步的程序運(yùn)行通過之后再繼續(xù)增加功能,這樣在檢查錯誤的時候比較有目的性,提高寫程序的效率。2、對于程序中的錯誤,如果遇到說變量沒有定義或者數(shù)據(jù)結(jié)構(gòu)沒定義的錯誤,可能是由于你在定義這種數(shù)據(jù)結(jié)構(gòu)的變量時數(shù)據(jù)結(jié)構(gòu)還沒有定義,也就是說在定義此數(shù)據(jù)結(jié)構(gòu)的變量的語句要放在聲明這種結(jié)構(gòu)體之后

8、。3、在寫程序時要注意printf和scanf語句的格式,格式不對會得不到你想要的結(jié)果。4、寫程序時一定要瞻前顧后,前后一致,包括名稱、數(shù)據(jù)類型等等。四、用戶手冊在使用程序時嚴(yán)格按照程序給出的提示一步一步來,下面給出程序正常執(zhí)行的步驟:1、程序會提示“請輸入迷宮的行數(shù),列數(shù)(包括外墻):”,這時就需要輸入表示迷宮的二維數(shù)組的行數(shù)和列數(shù),需要注意的是由于我們在迷宮周圍加了一道墻,所以要輸入的行列數(shù)要比實際表示迷宮的行列數(shù)多兩行兩列。2、程序提示“請輸入迷宮內(nèi)墻單元數(shù):”,此時需要輸入迷宮中墻的數(shù)目。3、程序提示“請依次輸入迷宮內(nèi)墻每個單元的行數(shù),列數(shù):”,此時要輸入迷宮中所有墻的坐標(biāo),我們用數(shù)組

9、中的一個元素來表示墻。4、在輸入了迷宮所有內(nèi)墻的坐標(biāo)后,程序會顯示出迷宮的結(jié)構(gòu),然后程序會提示“請輸入起點的行數(shù),列數(shù):”,此時需要輸入所求通路的起點坐標(biāo)。5、程序提示“請輸入終點的行數(shù),列數(shù):”,此時需要輸入所求通路的終點的坐標(biāo)。6、終點坐標(biāo)輸入完畢之后,程序會顯示出兩種運(yùn)行的結(jié)果,一種是輸出了迷宮的結(jié)構(gòu),此時迷宮中已包含了所找的通路,用連續(xù)的數(shù)字表示出了通路在迷宮中是如何走的,此時迷宮中的-1表示找通路時走過的單元但是通路不通。注意:再輸入內(nèi)墻單元的坐標(biāo)是一定要細(xì)心,不要錯輸,也不要漏輸。否則程序會出錯。五、測試結(jié)果迷宮的測試數(shù)據(jù)如下:左上角(1,1)為入口,右下角(9,8)為出口。 1

10、2 3 4 5 6 7 8001000100010001000001101011100100001000001000101011110011100010111000000程序的測試結(jié)果為:1、程序的開始界面2、輸入迷宮的行數(shù)列數(shù)之后3、輸入內(nèi)墻的個數(shù)之后4、再輸入了所有內(nèi)墻的坐標(biāo)后,程序會給出迷宮的結(jié)構(gòu)5、輸入所求通路的起點坐標(biāo)6、輸入所求通路的終點坐標(biāo)后會得到結(jié)果 結(jié)果以迷宮的形式輸出 結(jié)果用坐標(biāo)和下一位值的方向表示六、附錄(附有完整的源程序)源程序如下:#include"stdio.h"#include"stdlib.h"#define TRUE 1

11、#define FALSE 0#define OK 1#define ERROR 0#define OVERFLOW -2typedef int Status;#define STACK_INIT_SIZE 10 / 存儲空間初始分配量#define STACKINCREMENT 2 / 存儲空間分配增量struct PosType / 迷宮坐標(biāo)位置類型 int x; / 行值 int y; / 列值 ;struct SElemType / 棧的元素類型 int ord; / 通道塊在路徑上的序號 PosType seat; / 通道塊在迷宮中的坐標(biāo)位置 int di; / 從此通道塊走向下一

12、通道塊的方向(03表示東北) ;struct SqStack SElemType *base; / 在棧構(gòu)造之前和銷毀之后,base的值為NULL SElemType *top; / 棧頂指針 int stacksize; / 當(dāng)前已分配的存儲空間,以元素為單位; / 順序棧SqStack S;#define MAXLENGTH 25 / 設(shè)迷宮的最大行列為25typedef int MazeTypeMAXLENGTHMAXLENGTH; / 迷宮數(shù)組行列 / 全局變量 MazeType m; / 迷宮數(shù)組 int curstep=1; / 當(dāng)前足跡,初值為1 Status InitStack

13、(SqStack &S) / 構(gòu)造一個空棧S if(!(S.base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType) exit(OVERFLOW); / 存儲分配失敗 S.top=S.base; S.stacksize=STACK_INIT_SIZE; return OK; Status StackEmpty(SqStack S) / 若棧S為空棧,則返回TRUE,否則返回FALSE if(S.top=S.base) return TRUE; else return FALSE; Status Push(SqStack &am

14、p;S,SElemType e) / 插入元素e為新的棧頂元素 if(S.top-S.base>=S.stacksize) / 棧滿,追加存儲空間 S.base=(SElemType*) realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemType); if(!S.base) exit(OVERFLOW); / 存儲分配失敗 S.top=S.base+S.stacksize; S.stacksize+=STACKINCREMENT; *(S.top)+=e; return OK; Status Pop(SqStack &

15、S,SElemType &e) / 若棧不空,則刪除S的棧頂元素,用e返回其值,并返回OK;否則返回ERROR if(S.top=S.base) return ERROR; e=*-S.top; return OK; Status Pass(PosType b) / 當(dāng)迷宮m的b點的序號為0(可通過路徑),return OK; 否則,return ERROR。 if(mb.xb.y=0) return OK; else return ERROR; void FootPrint(PosType a) / 使迷宮m的a點的序號變?yōu)樽阚E(curstep) ma.xa.y=curstep; P

16、osType NextPos(PosType c,int di) / 根據(jù)當(dāng)前位置及移動方向,返回下一位置 PosType direc4=0,1,1,0,0,-1,-1,0; / 行增量,列增量 / 移動方向,依次為東南西北 c.x+=direcdi.x; c.y+=direcdi.y; return c; void MarkPrint(PosType b) / 使迷宮m的b點的序號變?yōu)?1(不能通過的路徑) mb.xb.y=-1; Status MazePath(PosType start,PosType end) / 算法3.3 / 若迷宮maze中存在從入口start到出口end的通道,

17、則求得一條 / 存放在棧中(從棧底到棧頂),并返回TRUE;否則返回FALSE PosType curpos; InitStack(S); SElemType e; curpos=start; do if(Pass(curpos) / 當(dāng)前位置可以通過,即是未曾走到過的通道塊 FootPrint(curpos); / 留下足跡 e.ord=curstep; e.seat.x=curpos.x; e.seat.y=curpos.y; e.di=0; Push(S,e); / 入棧當(dāng)前位置及狀態(tài) curstep+; / 足跡加1 if(curpos.x=end.x&&curpos.

18、y=end.y) / 到達(dá)終點(出口) return TRUE; curpos=NextPos(curpos,e.di); else / 當(dāng)前位置不能通過 if(!StackEmpty(S) Pop(S,e); / 退棧到前一位置 curstep-; while(e.di=3&&!StackEmpty(S) / 前一位置處于最后一個方向(北) MarkPrint(e.seat); / 留下不能通過的標(biāo)記(-1) Pop(S,e); / 退回一步 curstep-; if(e.di<3) / 沒到最后一個方向(北) e.di+; / 換下一個方向探索 Push(S,e);

19、curstep+; curpos=NextPos(e.seat,e.di); / 設(shè)定當(dāng)前位置是該新方向上的相鄰塊 while(!StackEmpty(S); return FALSE; void Print(int x,int y) / 輸出迷宮的解 int i,j; for(i=0;i<x;i+) for(j=0;j<y;j+) printf("%3d",mij); printf("n"); void main() PosType begin,end; int i,j,x,y,x1,y1; SElemType a; SqStack T;

20、InitStack(T); printf("請輸入迷宮的行數(shù),列數(shù)(包括外墻):"); scanf("%d%d",&x,&y); for(i=0;i<y;i+) / 定義周邊值為0(同墻) m0i=1; / 行周邊 mx-1i=1; for(j=1;j<x-1;j+) mj0=1; / 列周邊 mjy-1=1; for(i=1;i<x-1;i+) for(j=1;j<y-1;j+) mij=0; / 定義通道初值為0 printf("請輸入迷宮內(nèi)墻單元數(shù):"); scanf("%d",&j); printf

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論