八皇后問題 遞迴精講

2022-06-03 11:06:13 字數 3803 閱讀 3251

我們先來實現乙個非常熟悉的遞迴操作——階乘

那麼,不需要多說,相信好多同學都會想到如下**:

int factorial(int n) 

return n == 0 ? 1 factorial(n-1);

}

我們再來複習乙個曾經學習c的時候編寫過的乙個程式——兔子繁殖問題(斐波那契額數列)**如下:

int fibonacci(int n) 

return n <= 2 ? 1 : fibonacci(n-1) + fibonacci(n-2);

}

那麼,複習了遞迴的一些函式,我們現在來簡要總結一下遞迴優缺點

數學定義清晰,容易證明演算法的正確性和完備性

系統資源消耗大,每次函式的呼叫,都要消耗8b空間

(若不控制遞迴的深度,則很容易在造成「堆疊溢位」,造成程式崩潰)

會出現大量重複計算

現在我們就進入我們今天的主題——八皇后問題

那麼,什麼是八皇后問題呢?

在8×8格的西洋棋上擺放八個皇后,使其不能互相攻擊,

即:

任意兩個皇后不能處於同一行同一列同一斜線

在這裡,本人就來講解下三個核心函式思路

首先,有兩個函式需要我們 事先實現:

第乙個是:

存放 皇后 的棋盤該如何實現?

答曰:

二維陣列

在本題中,棋盤就是乙個8*8二維陣列

所以,**如下:

void drawchseeboard(int (*chessboard)[order]) 

printf("\n");

} printf("\n");

}

第二個 是:

檢測本行、本列是否安全

這個函式相對簡單,所以我們就不再進行詳細的解釋了,**段如下:

boolean issafe(int (*chessboard)[order], const int row, const int col) 

} for (i == row - 1, j = col; i >= 0; i--)

} for (i == row - 1, j = col + 1; i >= 0 && j < order; i--, j++)

} return true;

}

那麼,在以上的函式的基礎上,我們就來實現下最關鍵的部分——放置皇后函式:

void orderqueen(int (*chessboard)[order], const int row)  else 

chessboard[row][col] = 0; //去掉本位置的皇后(無論本行安全不安全)

//因為,下列需要放置乙個皇后!

} }}

以上,八皇后問題 就解決了!

那麼,現在我們來總結下我們編寫的程式:

#ifndef _mec_h_

#define _mec_h_

typedef unsigned char boolean;

#define true 1

#define false 0

#endif

#ifndef _eight_queen_h_

#define _eight_queen_h_

#include "mec.h"

#define order 8

boolean issafe(int (*chessboard)[order], const int row, const int col);

void drawchseeboard(int (*chessboard)[order]);

void orderqueen(int (*chessboard)[order], const int row);

#endif

#include #include "eightqueen.h"

void orderqueen(int (*chessboard)[order], const int row) else

chessboard[row][col] = 0;

} }}

void drawchseeboard(int (*chessboard)[order])

printf("\n");

} printf("\n");

}boolean issafe(int (*chessboard)[order], const int row, const int col)

} for (i == row - 1, j = col; i >= 0; i--)

} for (i == row - 1, j = col + 1; i >= 0 && j < order; i--, j++)

} return true;

}

還有就是我們呼叫這些函式的主函式了:

#include #include "eightqueen.h"

int main() ;

orderqueen(chess, 1);

return 0;

}

我們想要執行上述**,還是需要我們資料結構與演算法專欄一直都在強調的 運用命令列或者虛擬機器進行多檔案聯編至於遞迴運算,我們一定要進行手動的變數跟蹤,遞迴呼叫的操作十分單純,

但是在我們一直遞迴的過程中,就可能使得邏輯看起來十分複雜,這時候就需要我們進行變數跟蹤

程式設計的學習是戒驕戒躁的,

若是我們不能平靜心境取學習,

那麼,我們就很可能產生一些難以解決的問題

所以,在資料結構的學習中,我們要漸漸使得心境平和,並且在學習演算法的過程中能夠受到啟發,我認為,這就是我們學這門課的主要目的了

精講N皇后問題

思想 存三個陣列記錄記錄走的過程,運用回溯不符合或row n 1就跳出當前層,直到找完 遞迴時的路徑都在儲存著,當連續跳出到第一次進入的dfs且i n時就全部跳出dfs函式了 1 include2 include 3int n,sum 4int visit 3 100 5 int dp 11 6 v...

精講N皇后問題

思想 存三個陣列記錄記錄走的過程,運用回溯不符合或row n 1就跳出當前層,直到找完 遞迴時的路徑都在儲存著,當連續跳出到第一次進入的dfs且i n時就全部跳出dfs函式了 1 include2 include 3int n,sum 4int visit 3 100 5 int dp 11 6 v...

八皇后問題 遞迴

問題描述 在乙個8 8西洋棋盤上,有8個皇后,每個皇后佔一格 要求皇后間不會出現相互 攻擊 的現象,即不能有兩個皇后處在同一行 同一列或同一對角線上。問共有多少種不同的方法。程式 public void testeightprince 初始化,所有的位置都可以放置乙個皇后 for int x 0 x...