十一 遞迴與回溯 解決8皇后問題

2021-07-02 21:46:21 字數 1178 閱讀 4094

1、遞迴與回溯

程式設計中可利用函式的活動物件儲存回溯演算法的狀態資料,因此可以利用遞迴完成回溯演算法

2、八皇后問題

在乙個8×8西洋棋盤上,有有8個皇后,每個皇后佔一格;要求皇后間不會出現相互「攻擊」的現象,即不能有兩個皇后處在同一行、同一列或同一對角線上。

3、解決方案

演算法思路

初始化:i = 1

初始化:j = 1

從第i行開始,恢復j的當前值,判斷第j個位置

a.位置j可放入皇后:標記位置(i, j),i++ ,轉步驟2

b. 位置j不可放入皇后:j++,轉步驟a

c. 當j>8,i– ,轉步驟3

結束:

第8行有位置可放入皇后

#include 

#include

//定義棋盤,加邊界

#define n 8

static

char board[n+2][n+2];

//座標移動的偏移量

typedef

struct _struct_pos

pos;

pos pos[3] = ,,};

/* 初始化**,**有乙個邊框,存放著字元'#'

1-8行、列初始化為空 ' '

*/void init()

for(i = 1;i<=n;i++)

}}/*

用於顯示「棋盤」(二維陣列)

*/void display()

printf("\n");

}}/* 檢查i行,j列這個位置是否可以插入「皇后」

因為插入的順序是從上而下的(i=1 --> i=n ),所以檢查是否可以插入皇后時,

可只檢查插入位置的三個方向的上半部分位置有沒有皇后存在,避免多餘的計算量,

這三個方向的每次位置移動的偏移量定義在了pos結構陣列中

*/bool check(int i,int j)

} return ret;}/*

查詢位置,放入皇后

*/void find(int i)

else}}}

int main()

4、小結

遞迴回溯解決8皇后問題

今天學習了經典的8皇后問題,強化了對遞迴呼叫的理解,之前自己寫遞迴老是把出口條件理解錯,導致邏輯錯誤,時常拋棧溢位的錯誤.其實簡單來說遞迴呼叫,在呼叫之前,一定要想明白,遞迴出口在哪裡,在呼叫遞迴的時候,怎麼能讓遞迴的程式碼不斷向出口方向靠近,最終能找到遞迴的出口.這個問題想明白了,遞迴呼叫也就成功...

演算法 遞迴與回溯演算法解決八皇后問題

小結完整 在沒有其他演算法的加持下時,回溯演算法簡單來說,就是不斷試錯的過程。通過不斷向下乙個節點列舉尋找滿足條件的答案,當無法尋找到時,則返回至上乙個節點,然後繼續向下列舉。這句話可能看起來有點抽象,我們用乙個圖來演示一下。這是一張a村到e村的地圖。假設你從起點a出發到終點e 不是e1 在不知道路...

遞迴回溯解決八皇后問題

問題引入 解決思路 先放置第乙個皇后在第一行遍歷,確定第乙個皇后的列,然後利用遞迴放置下乙個皇后到下一行,並且放置途中需要判斷是否與之前放置的有衝突,直到8個皇后放置完畢,這就是一種解法,然後回溯,回到第8行繼續遍歷看是否有其它解法,如果沒有就繼續回溯到第七行遍歷,有的話就用遞迴找到下一行皇后放置的...