N皇后問題:遞迴加回溯(後續改進中)
阿新 • • 發佈:2018-12-19
遞迴思想本身就比較難以理解,再加上回溯,整個過程更加撲所迷離。其實對於複雜的遞迴過程特別是非尾遞迴,很多時候已經不能一步一步地去分析函式呼叫,因為這樣遲早會進死衚衕。設計一個遞迴程式時,只要從數學邏輯上建立好遞迴模型,然後將該模型翻譯成程式語言。
N皇后問題非常經典不需要重述,其實整個問題難點在於要找出所有的棋盤組合,試想如果只需要找出其中一種情況的話,問題就會簡單很多。以五皇后問題為例,從遞迴思想來看,如果要將五個皇后放好,必須先將四個皇后放好,依次類推直到一個皇后的情況。這樣實際上只需要寫出擺放棋子的程式然後遞迴呼叫就好了。
但是這種做法會導致兩個問題:1、如果皇后放到一半進行不下去了怎麼辦?2、得出了其中一種解後還想要其他解怎麼辦?其實這兩個問題可以合併成一個問題,這時候必然要通過回溯,每一步中都必須提供一個能回到前一步棋盤狀態的程式,因此在呼叫遞迴函式的後面應該有一個擦除當前狀態的程式。
整個程式虛擬碼應該為
void putqueen
{
if(沒有放完)
{
放棋子
if 找到一個解
輸出解
else
遞迴呼叫putqueen
擦除當前狀態
}