今天學習了經典的8皇后問題,強化了對遞迴呼叫的理解,之前自己寫遞迴老是把出口條件理解錯,導致邏輯錯誤,時常拋棧溢位的錯誤.
其實簡單來說遞迴呼叫,在呼叫之前,一定要想明白,遞迴出口在哪裡,在呼叫遞迴的時候,怎麼能讓遞迴的程式碼不斷向出口方向靠近,
最終能找到遞迴的出口.這個問題想明白了,遞迴呼叫也就成功了一半了.
之前在呼叫遞迴時還發現,遞迴說到底是通過棧進行計算,如果在遞迴裡呼叫了堆裡的東西,一定不能是new出來的物件.
而且遞迴呼叫時要盡量把呼叫遞迴用到的資源放到外面,減少遞迴呼叫的資源.
舉個簡單例子來說,寫乙個輸出重複語句的遞迴方法,程式碼本身沒問題,但是如果呼叫方法次數過多,仍然會丟擲棧溢位的錯誤.
用程式碼測試過,乙個簡單的輸出語句,在我電腦上,用string直接呼叫遞迴方法,一旦超過6200次就可能拋異常,
用stringbuilder呼叫遞迴方法,一旦超過12000次也可能拋異常
今天老師講的遞迴實現8皇后的方法確實很經典.占用資源也不多,但老師說,實際上這樣的演算法大概得呼叫14000多次遞迴方法
由此可見,其實遞迴方法程式碼占用的資源和程式碼本身的複雜程度關係並不大,關鍵還是看程式碼怎麼設計的,
怎麼能夠在呼叫時還能保證不占用過多的計算機資源.
以上就是我本人對於遞迴的一些粗淺的理解.
下面放上我重寫過的遞迴解決8皇后問題的程式碼.
1package
com.recursion;23
/*4* 遞迴回溯解決8皇后問題
5* 需求,根據象棋的規則,在棋盤上放置8個皇后,每個皇后的下一步棋不能吃子
6* 棋盤上放置到第8個皇后時,8個皇后的位置作為乙個正解,算出總共有多少正解7*
8* 遞迴回溯的思路
9* 將第乙個皇后放在第一行第一列,放第二個皇后,看下一步棋是否能吃子,
10* 不能吃子則放第三個皇后,放置下乙個子時,位置可能回溯,發生變化
11* 放到第8個皇后時開始回溯求解
12* 得到乙個正確解就會退回乙個棧,會把棧裡所有的可能性都嘗試一遍,
13* 退回上乙個棧,再次求解,一直回溯到第乙個皇后
14*
15*/
16public
class
eightqueen
3334
//3,定義放置皇后的方法,每一次進入check都會迴圈遞迴,知道得出正解
35private
void check(int
n) 41
//放置皇后,判斷是否衝突
42for (int i = 0; i < max; i++)
49//
如果衝突,遞迴繼續迴圈,去下一行50}
51}5253
//2,定義檢視放置第n個皇后是否滿足放置規則的方法
54/**
55*
56*
@param
n 表示第n個皇后
57*
@return
58*/
59private
boolean judge(int
n) 66}
67return
true;68
}6970//
1,定義列印輸出的方法
71private
void
print()
76system.out.println();77}
7879 }
程式碼不多,卻解決了乙個比較複雜的經典計算問題.
遞迴回溯解決八皇后問題
問題引入 解決思路 先放置第乙個皇后在第一行遍歷,確定第乙個皇后的列,然後利用遞迴放置下乙個皇后到下一行,並且放置途中需要判斷是否與之前放置的有衝突,直到8個皇后放置完畢,這就是一種解法,然後回溯,回到第8行繼續遍歷看是否有其它解法,如果沒有就繼續回溯到第七行遍歷,有的話就用遞迴找到下一行皇后放置的...
八皇后問題(遞迴,回溯)
八皇后問題是乙個以西洋棋為背景的問題 如何能夠在 8 8 的西洋棋棋盤上放置八個皇后,使得任何乙個皇后都無法直接吃掉其他的皇后?為了達到此目的,任兩個皇后都不能處於同一條橫行 縱行或斜線上。八皇后問題可以推廣為更一般的n皇后擺放問題 這時棋盤的大小變為n n,而皇后個數也變成n。當且僅當 n 1 或...
遞迴 回溯 八皇后問題
八皇后 問題,是乙個古老而著名的問題,是回溯演算法 的典型案例。該問題是國際西洋棋棋手馬克斯 貝瑟爾於1848年提出 在8 8格的西洋棋上擺放八個皇后,使其不能互相攻擊,即任意兩個皇后都不能處於同一行 同一列或同一斜線上,問有多少種擺法.輸入 無 輸出 8行8列的矩陣,0代表此處無皇后,1表示此處有...