你沒有太多的解決方案:基本上,探索無環迷宮是像做了深度優先搜索在覆蓋樹,每個路口是一個節點。
您可以隨時構建樹,並使用該信息來瀏覽它,但這會很單調乏味效率不高。
深度優先搜索的常用方法是推動堆棧中的所有節點進行檢查,拉動一個並再次推動,直到達到目標。但是你會得到很多節點堆積起來,一旦找到目標節點,就不能使用堆棧來知道你遵循的是哪條路徑,這意味着你需要在其他地方存儲這些信息。
這可能是更好的保持棧解決方案和標籤節點在你的籌碼來表示一個分支,和方向(即其子樹)的分支已經探索(或路徑剩下)。如果您在相同的順序做的探索始終,該標籤可以簡單地將一個數字:
或更好的是枚舉。
當找到死角時,只需展開堆棧直到找到其中一個節點,然後嘗試新的方向。如果所有方向都已經嘗試過,換句話說,如果沒有方向,請再次放鬆。
enum Branch {
LEFT,
FORWARD,
RIGHT,
BACKTRACK
};
struct BacktrackException{
};
template <typename MazeMove>
struct StackNode {
MazeMove move;
Branch branch;
StackNode(MazeMove m): move(m), branch(LEFT) {}
MazeMove nextBranch(){
switch(branch){
case LEFT:
if (move.can_left()){
branch = FORWARD;
return move.left();
}
case FORWARD:
if (move.can_forward()){
branch = RIGHT;
return move.forward();
}
case RIGHT:
if (move.can_right()){
branch = BACKTRACK;
return move.right();
}
default:
throw BacktrackException();
}
}
};
上面的代碼提供與棧使用的可能的「MazeMove」類,它保持跟蹤所嘗試的方向的一個包裝。 nextBranch方法返回下一個可能的移動,或者引發異常。
好處是你的堆棧不會被未經測試的移動破壞。每當你到達一個新的位置時,你推動一個StackNode
,當它的選項全部被測試出來時,將其展開。當你到達迷宮出口時,你的堆棧只包含需要的移動。
「我需要一個堆棧...所以沒有遞歸」 - 這是沒有意義的。謹慎解釋? – 2013-04-20 14:47:15
[迷宮問題和遞歸回溯算法](http:// stackoverflow。com/questions/4402846/maze-problem-and-recursive-backtracker-algorithm) – 2013-04-20 14:47:53
@ Moo-Juice這不是一個好的重複。這是一個迷宮解決的問題,但具體問題是完全不同的。 – 2013-04-20 14:50:48