在處理迷宮問題的時候,我想起了王道機試指南上的一端文字:
深度優先搜尋,它類似於人在迷宮中尋找出口:
每遇到乙個路口,先往乙個既定的方向走到底,直到發現出口或遇到死胡同。
發現死胡同後,就回到上乙個路口,並選擇另外乙個方向繼續尋找出口。
事實上,在處理迷宮問題時,我們也是使用這種思路。下面來介紹:
我們這樣描述迷宮:設定迷宮為二維陣列,陣列的值為
-1:代表牆
0:代表未走過的路徑
1:代表走不通的路徑
2:代表路徑
int mymap[10][10] =
;
並做出以下假設:迷宮入口為mymap[1][1],迷宮出口為mymap[8][8]。
我們嘗試使用遞迴策略來解決問題。
首先我們使用是乙個二維陣列direction[4][2],來設定搜尋方向:
int direction[4][2] =
,,,};
並按下列演算法解決問題:
1. 如果當前位置為出口,結束。
2. 否則:
//遞迴解決迷宮問題
#include#includeusing namespace std;
int mymap[10][10] =
;struct point
};int direction[4][2] =
,,,};
int goal(point cur, point end)
else
mymap[cur.row][cur.col] = 1;
} return 0;
}void print()
printf("\n");
} return;
}//列印迷宮
void printpath()
cout << endl;
} cout << endl;
}int main()
看起來,思路好像很簡單。實際上筆者花費了大半天的時間才看明白。。雖然一部分原因拜vs的逐步除錯所賜。。
相比之下,使用棧來解決迷宮問題的**相當簡潔:
//棧解決迷宮問題
#include#include#includeusing namespace std;
int mymap[10][10] =
;struct point
};void masepath(point start, point end)
} while ((p.row != end.row) || (p.col != end.col));
return;
}void print()
printf("\n");
} return;
}//列印迷宮
void printpath()
cout << endl;
} cout << endl;
}int main()
其解決思路類似:
1. 當前位置入棧
2. 判斷下一步是否可行,
若可行 ,則返回步驟1
若不可行,則換方向繼續嘗試
3. 若四個方向均不可行,則當前位置出棧。回到前乙個位置,換方向搜尋。
哎呀。。迷宮問題也算是乙個經典問題了
不過我只能想出來第一種遞迴方法,使用棧進行處理的操作還是需要進一步理解。
如果說迷宮問題的變體的話,那就是如何輸出迷宮的所有可能路徑呢???
留給以後來探索...
資料結構之 棧和遞迴 函式呼叫
更正 以下所指ebx應改為eax。ebx指 基位址 暫存器,在記憶體定址時存放基位址 eax是累加器 accumulator 一般用來儲存函式的返回值。首先說說遞迴的實現和棧的關係吧,這裡引入乙個著名的尾遞迴 斐波那契數列的實現,我用的是c語言編寫該函式,int fib int n 我們不妨把函式f...
資料結構 二 棧 佇列 遞迴
1.用陣列實現乙個順序棧 用陣列實現乙個順序棧 define maxsize 64 棧的最大容量 typedef struct sqstack,sqslink 順序棧說明符 置棧空 void clearstack sqslink s 判棧空 intemptystack sqslink s 元素x進棧...
資料結構 分治策略與遞迴(一)
分治策略是將規模比較大的問題可分割成規模較小的相同問題。問題不變,規模變小。這就自然導致遞迴過程的產生。遞迴是指乙個函式能夠直接或者間接的調動自己,就稱之為遞迴函式 自己呼叫自己 分治法所能解決的問題一般具有以下特徵 分治法步驟 比如說求n 這個問題就適合用分治的策略來求解,我們將乙個問題的規模縮小...