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行繼續遍歷看是否有其它解法,如果沒有就繼續回溯到第七行遍歷,有的話就用遞迴找到下一行皇后放置的...