在探迷宮 2 迷宮路徑之最優解 帶環或不帶環

2021-08-23 14:40:39 字數 2950 閱讀 4039

迷宮問題(1)–課程設計之簡單實現(只找出一條通路即可)

因為迷宮問題需要用到棧,所以貼出棧的相關操作的鏈結

棧的基本操作

棧的相關面試題總結

迷宮地圖的分類(大概有三種)

第一類:乙個入口(entry),乙個出口(exit),而且通路不帶環,只有一條通路。

思路:首先,將入口座標壓入棧中,確定棧頂元素入口座標為當前位置,並且將走過的座標標記,以免走回頭路。從當前位置開始探索上下左右四個方向,能通過則壓棧繼續切換當前位置前進,但是如果遇到死胡同(四個方向都不通),則回溯,既出棧一次,把棧頂座標當做是當前位置,繼續探索。探索過程中如果遇到終點,則直接結束;如果沒有終點,則會一直回溯到起點,這時棧一定為空。此時,迷宮沒有通路。

//給定乙個終點,確定下乙個結點是否可通

int checkaccess_e(pos cur)

else

}//乙個入口,乙個出口,求一條通路(返回1有通路,返回0沒有通路)

int getmazepath_e(pos entry, pos exit)

//右,切換座標位置

next = cur;

next._col += 1;

if (checkaccess_e(next))

//左next = cur;

next._col -= 1;

if (checkaccess_e(next))

//下next = cur;

next._row += 1;

if (checkaccess_e(next))

//上next = cur;

next._row -= 1;

if (checkaccess_e(next))

//當前座標不通,則出棧回溯,把上乙個結點當做當前位置繼續探索

stackpop(&s);

}return

0;}

第二類:只給乙個入口(entry),然後在一側有多個出口(exit),必然有多條路徑可通,怎麼樣才能求得一條最短的路徑?
思路:在求解第一類迷宮的基礎上,當遇到乙個終點的時候,不要直接返回程式,而是繼續探索回溯,找到下乙個終點,繼續回溯。然後,設定乙個全域性的變數來記錄最短路徑的長度,第一次到達終點,把路徑長度賦值給全域性變數,在以後的回溯中遇到終點則比較,如果小於全域性變數的值,則更新。

//乙個入口,多個出口,求一條最短通路

int pathsize=0;//全域性變數,標記最短路徑

void getmazepath_m(pos entry)

}//右,切換座標位置

next = cur;

next._col += 1;

if (checkaccess_e(next))

//左next = cur;

next._col -= 1;

if (checkaccess_e(next))

//下next = cur;

next._row += 1;

if (checkaccess_e(next))

//上next = cur;

next._row -= 1;

if (checkaccess_e(next))

//當前座標不通,則出棧回溯,把上乙個結點當做當前位置繼續探索

stackpop(&s);}}

上邊的**雖然很好的求出來最小路徑,但是這個程式是有侷限性的,它值適用於對迷宮路徑中不帶環的通路進行求解,如果迷宮中的路徑是帶環的,這道題的解法就是錯誤的,當然結果取決於切換下乙個當前位置的方向,如果結果是正確的,也只能是運氣好,但是思路是錯誤的。第三類:通路間帶環,怎麼求解最短路徑?

思路:換一種標記方式,從入口開始標記2,然後後邊標記的值依次比前面標記的值要大於1。既然標記方式被改變了,那麼回溯到前乙個座標時再去檢查前乙個座標的下乙個位置是否可通的方法也就被改變了。

//通路存在環,換一種標記方式,也要換一種檢查是否可通的方式

int checkaccess(pos cur, pos next)

else

}//給定乙個終點,確定下乙個結點是否可通

int checkaccess_e(pos cur)

else

}//通路之間帶環

void getmazepath_c(pos entry)

}//右,切換當前位置

next = cur;

next._col += 1;

if (checkaccess(cur, next))

//左next = cur;

next._col -= 1;

if (checkaccess(cur, next))

//下next = cur;

next._row += 1;

if (checkaccess(cur, next))

//上next = cur;

next._row -= 1;

if (checkaccess(cur, next))

//當前座標不通,則回溯出棧

stackpop(&s);}}

為了測試方便,寫乙個列印迷宮的函式

//遍歷二維陣列列印迷宮

void printmaze(int maze[n][n])

printf("\n");

}}

將迷宮列印出來,我們就可以清楚的看到迷宮的通路和我們做的標記。

尋找迷宮路徑

尋找迷宮路徑其實就是遍歷每乙個可能的路徑,碰到能夠成功的路徑就返回。bool findpath position here here.row 1 here.col 1 maze 1 1 1 防止回到入口 int option 0 下一步 int lastoption 3 尋找一條路徑 while h...

搜尋迷宮路徑

從入口出發,按某一方向向前探索,若能走通則到達新點,並試探下一方向 若所有方向均沒有通路,則沿原路返回前一點,換下乙個方向再繼續試探,知道所有可能的路徑都試探到,或找到出口,或者無路可走退回到入口.為了能夠保證在到達某一點後不能繼續向前走時能退回到上乙個點並繼續進行下乙個方向的探尋,則需要有乙個能滿...

迷宮的最優路徑

對於迷宮最優路徑,其中之一方法就是把所有路徑都找出來如下 1 1 1 1 1 1 1 1 1 1 對於這樣的迷宮,從 0 0 到 4 4 所有路徑有 00 01 11 21 31 41 31 32 33 34 44 以及 00 01 11 21 31 32 33 34 44 這樣在一條路徑重複走同一...