利用棧實現迷宮的求解_第1頁
利用棧實現迷宮的求解_第2頁
利用棧實現迷宮的求解_第3頁
利用棧實現迷宮的求解_第4頁
利用棧實現迷宮的求解_第5頁
已閱讀5頁,還剩4頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、利用棧實現迷宮的求解一、要解決的問題:以一個m*n的長方陣表示迷宮,0和1分別表示迷宮中的通路和障礙,設計一個程序,對任意設定的迷宮,求出一條從入口到出口的通路,或得出沒有通路的結論。二:算法基本思想描述:用一個字符類型的二維數組表示迷宮,數組中每個元素取值“0”(表示通路)或“1”(表示墻壁)。二維數組的第0行、第m+1行、第0列、第m+1列元素全置成“1”, 表示迷宮的邊界;第1行第1列元素和第m行第n列元素置成“0”, 表示迷宮的入口和出口走迷宮的過程可以模擬為一個搜索的過程:每到一處,總讓它按東、南、西、北4個方向順序試探下一個位置;用二維數組move記錄4個方向上行下標增量和列下標增

2、量,則沿第i個方向前進一步,可能到達的新位置坐標可利用move數組確定: Px=x+movei0 Py=y+movei1如果某方向可以通過,并且不曾到達,則前進一步,在新位置上繼續(xù)進行搜索;如果4個方向都走不通或曾經到達過,則退回一步,在原來的位置上繼續(xù)試探下一位置。三:設計:1:數據結構的設計:(1)定義三元數組元素的結構typedef struct MazeDirect int Dx; /行標 int Dy; /列標 int direct; /走到下一個坐標點的方向MazeDirect; (2)定義鏈表節(jié)點的結構組成typedef struct LinkNode elemtype data

3、; /數據域 struct LinkNode *next; /指針域LinkNode;(3)定義鏈棧的頭指針typedef struct LinkNode *top; /棧的頭指針LinkStack;(4)移動數組結構的定義typedef struct int x,y;/x為行標,y為列標Direction_increm;2:算法的設計:【1】迷宮圖的設計設迷宮為m行n列,利用mazemn來表示一個迷宮,mazeij=0或1; 其中:0表示通路,1表示不通,當從某點向下試探時,中間點有4個方向可以試探,(見圖)而四個角點有2個方向,其它邊緣點有3個方向,為使問題簡單化我們用mazem+2n+2

4、來表示迷宮,而迷宮的四周的值全部為1。這樣做使問題簡單了,每個點的試探方向全部為4,不用再判斷當前點的試探方向有幾個,同時與迷宮周圍是墻壁這一實際問題相一致。假設有6行8列的迷宮,如下圖為maze810構造的迷宮1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 1 1 1 1 1 0 0 1 0 1 1 1 1 1 1 0 0 0 0 0 0 0 1 1 1 0 0 1 1 0 1 1 1 1 1 1 0 0 0 1 0 0 0 1 1 0 1 1 0 0 0 1 0 1 1 1 1 1 1 1 1 1 1 1【2】試探方向的設計:在上述表示迷宮的情況下,每個點有4個方向去試探,

5、如當前點的坐標(x , y),與其相鄰的4個點的坐標都可根據與該點的相鄰方位而得到,如圖2所示。因為出口在(m,n),因此試探順序規(guī)定為:從當前位置向前試探的方向為從正東沿順時針方向進行。為了簡化問題,方便的求出新點的坐標,將從正東開始沿順時針進行的這4個方向(用0,1,2,3表示東、南、西、北)的坐標增量放在一個結構數組move 4 中,在move 數組中,每個元素有兩個域組成,x:橫坐標增量,y:縱坐標增量。Move數組如圖3所示。move數組定義如下:typedef struct int x ; /行int y ; /列 item ; item move4 ;這樣對move的設計會很方便

6、地求出從某點 (x,y) 按某一方向 v (0v3) 到達的新點(i,j)的坐標:i =x + movev.x ,j = y + movev.y 。(x,y)圖2 與點(x,y)相鄰的4個點及坐標(x,y+1)(x,y-1)(x+1,y)(x-1,y)xy00111020-13-10圖3 增量數組move【3】棧的設計:當到達了某點而無路可走時需返回前一點,再從前一點開始向下一個方向繼續(xù)試探。因此,壓入棧中的不僅是順序到達的各點的坐標,而且還要有從前一點到達本點的方向,即每走一步棧中記下的內容為(行,列,來的方向)。對于圖1所示迷宮,依次入棧為:top >3,4,0 3,3,0 3,2,

7、1 2,2,0 2,1,1 1,1,0棧中每一組數據是所到達的每點的坐標及從該點沿哪個方向向下走的,對于圖3迷宮,走的路線為:(1,1,0)à(2,1,1)à(2,2,0)à(3,2,1)à(3,3,0)à(3,4,0)(下腳標表示方向),當無路可走,則應回溯,對應的操作是出棧,沿下一個方向即方向繼續(xù)試探。棧中元素是一個由行、列、方向組成的三元組,棧元素的設計如下:typedef structint x , y , d ;/* 橫縱坐標及方向*/datatype ;棧的定義為: SeqStack s ;【4】. 如何防止重復到達某點,以避免發(fā)生

8、死循環(huán):一種方法是另外設置一個標志數組markmn,它的所有元素都初始化為0,一旦到達了某一點 ( i , j )之后,使mark i j 置1,下次再試探這個位置時就不能再走了。另一種方法是當到達某點(i , j)后使maze i j 置 -1,以便區(qū)別未到達過的點,同樣也能起到防止走重復點的目的,此處采用后一方法,算法結束前可恢復原迷宮。四:詳細設計;1. 算法的設計思想及流程圖(1)主要函數的功能說明 void ini_stack(LinkStack *)/*初始化鏈棧*/ int empty_Stack(LinkStack *)/*判斷是否為空棧*/ void push_Stack(L

9、inkStack *,elemtype)/*入棧*/ elemtype pop_Stack(LinkStack *) /*出棧*/ int size_stack(LinkStack ) /*棧的規(guī)模大小*/ (2) 算法描述【偽代碼描述】迷宮求解算法思想如下:(1) 棧初始化;(2) 將入口點坐標及到達該點的方向(設為-1)入棧(3) while (棧不空) 棧頂元素(x , y , d)出棧 ;求出下一個要試探的方向d+ ;/當遇到死路的時候就出棧,尋找原來點的下一個方向 while (還有剩余試探方向時) if (d方向可走)則 (x , y , d)入棧 ; 求新點坐標 (i, j )

10、;將新點(i , j)切換為當前點(x , y) ; if ( (x ,)= =(,n) ) 結束 ; else 重置 d=0 ; else d+ ; 五:源程序清單;#include <stdio.h>#include <stdlib.h>int m,n;typedef struct MazeDirect int Dx; int Dy; int direct;MazeDirect; /*定義三元數組元素的結構*/typedef MazeDirect elemtype;typedef struct LinkNode elemtype data; struct LinkN

11、ode *next; /*定義鏈表節(jié)點的結構組成*/LinkNode;typedef struct LinkNode *top; /*定義鏈棧的頭指針*/LinkStack;void ini_stack(LinkStack *stack)/*初始化鏈棧*/ stack->top=NULL;int empty_Stack(LinkStack *stack)/*判斷是否為空棧*/ if (stack->top!=NULL) return 0; else return 1;void push_Stack(LinkStack *stack,elemtype x)/*入棧*/ LinkNod

12、e *s; s=(LinkNode *)malloc(sizeof(LinkNode); s->data=x; s->next=stack->top; stack->top=s;elemtype pop_Stack(LinkStack *stack) /*出棧*/ elemtype x; LinkNode *p; elemtype tmpNull=0,0,0; if (stack->top=NULL) return tmpNull;/(NULL) else x=stack->top->data; p=stack->top; stack->t

13、op=p->next; free(p); return (x); int size_stack(LinkStack stack) /*棧的規(guī)模大小*/ int i; LinkNode *Numb; i=0; Numb=stack.top; while(Numb!=NULL) Numb=Numb->next; i+; return i;int w,t,maze100100;typedef struct int x,y;/x為行標,y為列標Direction_increm;Direction_increm MazeMove4=0,1,1,0, 0,-1,-1,0;typedef Maz

14、eDirect TmpType;int Maze_path() MazeDirect tmp,path; LinkStack s; int x,y,Px,Py,d,flag=0; ini_stack(&s); tmp.Dx=1;tmp.Dy=1;tmp.direct=-1; push_Stack(&s,tmp); while (!empty_Stack(&s) tmp=pop_Stack(&s); x=tmp.Dx;y=tmp.Dy;d=tmp.direct+1;/遇到死路的時候,回溯(通過出棧完成) while (d<4) Px=x+MazeMoved.

15、x; Py=y+MazeMoved.y; if (mazePxPy=0) tmp.Dx=x; tmp.Dy=y; tmp.direct=d; push_Stack(&s,tmp); x=Px;y=Py;mazexy=-1;/*標記,防止重復點*/ if(x=m&&y=n) flag=1; printf("n到達迷宮出口:%d,%d",x,y); printf("n經過的節(jié)點有:%d個",size_stack(s); while(!empty_Stack(&s) path=pop_Stack(&s); printf("n(%d,%d,%d)",path.Dx,path.Dy,path.direct); break; else d=0; /結束if else d+; /結束內部while /結束外部while return flag;void main() printf("請輸入迷宮圖的行數和列數(

溫馨提示

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

評論

0/150

提交評論