遞迴回顧(迷宮問題,八皇后問題)

2022-09-09 20:51:30 字數 3501 閱讀 9482

簡單的說:遞迴就是方法自己呼叫自己,每次呼叫時傳入不同的變數,遞迴有助於程式設計者解決複雜的問題,同時讓**變得簡潔。

**遞迴呼叫規則:**

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

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 }

八皇后問題:在乙個 8 * 8 的西洋棋上擺放八個皇后,使其不能相互攻擊,即:**任意兩個皇后不能處於同一行,同一列,或者同一斜線上,問有多少種擺法**

思路分析:

1. 第乙個皇后先放第一行第一列

2. 第二個皇后放在第二行第一列,然後夠判斷是否ok,如果不ok,就放在第二列,第三列,一次把所有列都放完,找到乙個合適的

3. 繼續放第三個皇后,還是第一列,第二列,.... 直到第八個皇后也能放在乙個不衝突的位置,算是找到乙個正確解

4. 當得到乙個正確解時,在棧回退到上乙個棧時,就會開始回溯,即將第乙個皇后,放到第一列的所有的正確解全部得到

5. 然後回頭繼續第乙個皇后放第二列,後面繼續迴圈執行

說明:理論上應該建立乙個二維陣列來表示棋盤,但是實際上可以通過演算法用乙個一維陣列即可解決,下標表示第幾行,也表示第幾個皇后,而陣列裡面的數,就是第幾列 `arr[0] = 1`: 第乙個皇后在第0 + 1行,1+1列

1

package 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.在第二行適合的位置 不在上...