小結完整**
在沒有其他演算法的加持下時,回溯演算法簡單來說,就是不斷試錯的過程。通過不斷向下乙個節點列舉尋找滿足條件的答案,當無法尋找到時,則返回至上乙個節點,然後繼續向下列舉。
這句話可能看起來有點抽象,我們用乙個圖來演示一下。
這是一張a村到e村的地圖。假設你從起點a出發到終點e(不是e1),在不知道路怎麼走且時間、精力充足的情況下,你會選擇一條條路走過去,直到找到終點e為止。
當你從起點a出發時,在你面前的就是b1、b2兩條路。由於你你不知道哪條路是正確的,你只能通過試錯來排除錯誤路徑。當你選擇b2並走到b2時,你發現接下來擺在你面前的只有c4一條路,於是你毫不猶豫的走進了c4。但很可惜,c4之後已經沒有路可以走了。於是你便返回到b2,並在通往c4的路上插了面小紅旗,告訴自己這條路已經走過了,無法通往e村。接著你發現,b2之後除了c4沒有其他路可以走,於是你就只能繼續返回到起點a,並在通往b2的路上也插了面小紅旗,告訴自己只要走b2就無法通往e村。於是你就開始走b1路,如此往復:當發現路無法繼續向下走時,便返回上乙個路口,並把該路標記為走不通,然後走下一條路(如果沒有下一條路的話,則繼續返回上乙個路口)。
總的流程圖將會是這樣的:
如果走到n=1且觀察到接下來沒有未標記的路(n=n-1==0),就說明沒有一條路能夠達到目標地點。
在 8×8 格的西洋棋上擺放八個皇后,使其不能互相攻擊,即任意兩個皇后都不能處於同一行、同一列或同一斜線上。
實現八皇后的目的:求出有多少種擺法。
通過上面的找路的例子可以發現,回溯演算法的核心類似於窮舉法,嘗試每一條不同的路徑,然後記錄下滿足需求的,拋棄不滿足的。
因此八皇后問題就可以用下面這種方式解決:
建立乙個8*8的二維陣列來表示乙個棋盤。
先在array[0][0]處放置第乙個皇后,然後檢視array[1][0]是否滿足,若不滿足則繼續嘗試array[1][1],array[1][2]…直至滿足條件後放第二個皇后,然後檢索第三個皇后的位置,檢索方法同第二個皇后,直到第八個皇后放完。
當第八個皇后放好後(假設位於array[7][3]),則返回到第七個皇后,繼續檢索array[7][4]滿不滿足條件。直到檢索出全部情況為止。
實現八皇后問題的關鍵有兩點:
判斷皇后放置的位置是否滿足遊戲條件
利用遞迴和回溯放置皇后到棋盤上
因此,我們在解決八皇后問題時,最主要的就是先把判斷皇后位置是否正確的方法寫出來。
tips:這裡用了個小小的演算法,用一維陣列來實現棋盤。具體實現如下:
3. 定義int array[8]陣列
4. array[n] = value 代表第n + 1個皇后(陣列下標從0開始)位於棋盤的第n+1行的第value + 1 列上。
/**
* 先定義乙個類,確定棋盤大小並定義完棋盤陣列array。
* count 用於記錄總共有多少種解法
*/class
eightqueens
public
boolean
judge
(int n)
}return
true
;}
擁有這個判斷方法之後,就可以通過遞迴和回溯,找到正確的八皇后解法了。
接下來構寫乙個方法開始放第乙個皇后
/**
* 該check方法在主方法被呼叫時,引數n只能傳入0,因為皇后只能從第0個開始放
*/public
void
check
(int n)
for(
int i =
0; i < max; i++
)//當皇后n judge判斷未通過而返回到皇后n-1級時,將會位於這個位置。
//接下來將執行的操作時for迴圈中的i++
}//當執行完for迴圈後,說明該行所有列都已經被judge過了,就return到上一級
}
構寫乙個主類和主函式檢查上述方法是否正確
public
class
test
}
其實單純的回溯演算法並不高效,簡單來說就是將所有能產生的情況全部列舉出來,然後找到正確答案。如果你願意的話,在judge函式中加入乙個計數器,就可以發現整個過程下來,judge函式執行了1.5w+次,所以需要加入其他演算法來優化。不過這也反映出遞迴與回溯的本質就是試錯法,或者說是窮舉法。
public
class
eightqueens
}return
true;}
public
void
check
(int n)
for(
int i =
0; i < max; i++)}
}public
void
print()
system.out.
println();}}
public
class
test
}
打靶 遞迴演算法 八皇后 回溯演算法
面試例題1 乙個射擊運動員打靶,靶一共有10環,連開10槍打中90環的可能性有多少種?請用遞迴演算法程式設計實現。中國某著名通訊企業h面試題 解析 靶上一共有10種可能 1環到10環,還有可能脫靶,那就是0環,加在一起共11種可能。這是一道考迴圈和遞迴的面試題。我們在這個程式中將利用遞迴的辦法實現打...
回溯遞迴演算法 八皇后問題
前,有皇帝。就拿八皇后。由此產生的一系列問題,凌亂。由此產生的八皇后問題。哈哈 開玩笑 八皇后問題,是乙個古老而著名的問題,是回溯演算法的典型案例。該問題是國際西洋棋棋手馬克斯 貝瑟爾於1848年提出 在8x8格的西洋棋上擺放八個皇后,使其不能互相攻擊,即隨意兩個皇后都不能處於同一行 同一列或同一斜...
遞迴 八皇后問題(回溯演算法)
問題 在8x8的西洋棋的棋盤上擺八個皇后,使其不能夠互相攻擊。即任意兩個皇后不能夠處在同一行,同一列,或者是同一斜線,問有多少種擺法?92 思路分析 第乙個皇后放在第一行的第一列 第二個皇后從第二行第一列開始放,然後判斷可不可以,可以,就放第三個皇后,也從第三行第一列開始放 不可以在換下乙個位置,在...