簡單的說:遞迴就是方法自己呼叫自己,每次呼叫時傳入不同的變數,遞迴有助於程式設計者解決複雜的問題,同時讓**變得簡潔。
**遞迴呼叫規則:**
1. 當程式執行到乙個方法的時候,就會開闢乙個獨立的空間棧
2. 每個空間的資料(區域性變數),是獨立的
列印問題
8public
static
void test(int
n)12 system.out.println("
n=" +n);13}
14//
階乘問題
15public
static
int factorial(int
n) else21}
22 }
1. 執行乙個方法時,就建立乙個新的受保護的獨立空間(棧空間)
2. 方法的區域性變數是獨立的,不會相互影響
3. 如果方法中使用的是引用型別的變數,就會共享該引用型別的資料
4. 遞迴必須向推出條件逼近,否則就是無限遞迴(stackoverflowerror),死歸了
5. 當乙個方法執行完畢,或者遇到return,就會返回,遵守誰呼叫,就將結果返回給誰,同時當方法執行完畢或者返回時,該方法也將執行完畢
### 8.3 遞迴 - 迷宮問題
說明:1. 小球得到的路徑,和程式設計師設定的找路策略有關,找路的上下左右的順序相關
2. 再得到小球路徑時,可以先使用(下右上左),再改成(上右下左),看看路徑是不是有變化
3. 測試回溯現象
4. 思考:**如何求出最短路徑**
1八皇后問題:在乙個 8 * 8 的西洋棋上擺放八個皇后,使其不能相互攻擊,即:**任意兩個皇后不能處於同一行,同一列,或者同一斜線上,問有多少種擺法**package recursion;23
public
class
migong
14//
再把左右置為1
15for (int i = 0; i < 8; i++)
1920
//設定擋板
21 map[3][1] = 1
;22 map[3][2] = 1;23
//輸出地圖
24 system.out.println("
map:");
25for (int i = 0; i < 8; i++)
29 system.out
.println();30}
3132
//使用遞迴回溯給小球找路
33 setway(map, 1, 1
);34
//輸出新的地圖,小球走過,並標識過的遞迴
35//
輸出地圖
36 system.out.println("
map2:");
37for (int i = 0; i < 8; i++)
41 system.out
.println();42}
43}4445
//使用遞迴回溯給小球找路
46//
說明47
//1. map 表示地圖
48//
2. i, j 表示從地圖的哪個位置出發
49//
3. 如果小球能到 map[6][5] 位置 這說明通路找到
50//
4. 約定,當map[i][j] 為0 表示 該店沒有走過 當為 1 時表示牆,2 表示通路可以走, 3 表示該店已經走過,但是走不通
51//
5. 在走迷宮時,需要確定乙個策略,下 - 右 - 上 - 左,如果該點走不通在回溯
52/**53
*54* @param map 表示地圖
55* @param i 從哪個位置開始
56* @param j
57* @return 如果找到通路,就返回true,否則就返回false
58*/
59public
static boolean setway(int map, int i, int
j) else
else
if (setway(map, i, j + 1
)) else
if (setway(map, i - 1
, j)) else
if (setway(map, i, j - 1
)) else
84 } else88}
89}90 }
思路分析:
1. 第乙個皇后先放第一行第一列
2. 第二個皇后放在第二行第一列,然後夠判斷是否ok,如果不ok,就放在第二列,第三列,一次把所有列都放完,找到乙個合適的
3. 繼續放第三個皇后,還是第一列,第二列,.... 直到第八個皇后也能放在乙個不衝突的位置,算是找到乙個正確解
4. 當得到乙個正確解時,在棧回退到上乙個棧時,就會開始回溯,即將第乙個皇后,放到第一列的所有的正確解全部得到
5. 然後回頭繼續第乙個皇后放第二列,後面繼續迴圈執行
說明:理論上應該建立乙個二維陣列來表示棋盤,但是實際上可以通過演算法用乙個一維陣列即可解決,下標表示第幾行,也表示第幾個皇后,而陣列裡面的數,就是第幾列 `arr[0] = 1`: 第乙個皇后在第0 + 1行,1+1列
1package recursion;23
public
class
queen8
16//
編寫乙個方法,放置第 n 個皇后
17private
void check(int
n)23
//依次放入皇后,並判斷是否衝突
24//
特別注意:check 時每一遞迴時,進入到check中都有for(int i = 0; i < max; i++),因此會回溯
25for (int i = 0; i < max; i++)
33//
如果衝突,就繼續執行array[n] = i, 即34}
35}36//
檢視當我們擺放第n個皇后,就去檢測該皇后是否和前面已經擺放的皇后衝突,即將第n個皇后,放置在本行得後移乙個位置
3738/**
39*40* @param n 表示第n個皇后
41* @return
42*/
43private boolean judge(int
n)53}54
return
true;55
}56//寫乙個方法,將皇后擺放的位置擺放的位置輸出
57private
void
print()
62 system.out
.println();63}
64 }
八皇后問題(遞迴,回溯)
八皇后問題是乙個以西洋棋為背景的問題 如何能夠在 8 8 的西洋棋棋盤上放置八個皇后,使得任何乙個皇后都無法直接吃掉其他的皇后?為了達到此目的,任兩個皇后都不能處於同一條橫行 縱行或斜線上。八皇后問題可以推廣為更一般的n皇后擺放問題 這時棋盤的大小變為n n,而皇后個數也變成n。當且僅當 n 1 或...
遞迴 回溯 八皇后問題
八皇后 問題,是乙個古老而著名的問題,是回溯演算法 的典型案例。該問題是國際西洋棋棋手馬克斯 貝瑟爾於1848年提出 在8 8格的西洋棋上擺放八個皇后,使其不能互相攻擊,即任意兩個皇后都不能處於同一行 同一列或同一斜線上,問有多少種擺法.輸入 無 輸出 8行8列的矩陣,0代表此處無皇后,1表示此處有...
遞迴回溯 八皇后問題
八皇后問題 西洋棋中皇后能橫向,縱向和斜向移動,在這三條線上的其他棋子都可以被吃掉。所謂八皇后問題就是 將八位皇后放在一張8x8的棋盤上,使得每位皇后都無法吃掉別的皇后,即任意兩個皇后都不在同一條橫線,豎線和斜線上 問一共有多少種擺法?解決思路 1.將第一行第一列放入 2.在第二行適合的位置 不在上...