代码
#include <stdio.h>
#include <malloc.h>
#include <math.h>
#include <stdbool.h>
#include <stdlib.h>
// 测试一下放在这个位置可以吗
bool place(int* paraSolution, int paraT){
int j;
for (j = 1; j < paraT; j ++){
if ((abs(paraT - j) == abs(paraSolution[j] - paraSolution[paraT])) || (paraSolution[j] == paraSolution[paraT]))
return false;
}
return true;
}
void backtracking(int* paraSolution, int paraN, int paraT){
int i;
if (paraT > paraN){
for (i = 1; i <= paraN; i ++)
printf("%d ", paraSolution[i]);
printf("\r\n");
}else{
for (i = 1; i <= paraN; i ++){
paraSolution[paraT] = i;
if (place(paraSolution, paraT))
backtracking(paraSolution, paraN, paraT + 1);
}
}
}
void nQueen(int paraN){
int i;
int* solution = (int*)malloc((paraN + 1) * sizeof(int));
for (i = 0; i <= paraN; i ++)
solution[i] = 0;
backtracking(solution, paraN, 1);
}
int main(){
nQueen(5);
return 1;
}
运行结果
心得体会
N皇后问题是一个经典的回溯算法问题。我们需要通过不断地试错和回溯来找到所有可能的解决方案。
place 函数用于检查在给定位置放置皇后是否安全。它通过遍历已经放置的皇后,检查新位置是否与它们在同一行、列或斜线上。
backtracking 函数是递归的核心。它尝试在棋盘的每一行放置皇后,并使用place函数来检查放置是否安全。如果安全,则递归地尝试放置下一个皇后。
代码实现:
你使用了动态内存分配来创建solution数组,这是一个很好的做法,因为它允许我们处理任意大小的N。
数组索引从1开始而不是从0开始,这在处理棋盘位置时可能更直观,但需要注意在C语言中数组索引通常从0开始。
在backtracking函数中,你使用了for循环来尝试所有可能的列位置。这是回溯算法的一个关键部分:尝试所有可能的选项,并在需要时回溯。
通过编写N皇后问题的解决方案,我加深了对回溯算法和递归的理解。我意识到在解决复杂问题时,将问题分解为更小的子问题并尝试所有可能的解决方案是非常重要的。
我也意识到优化代码的重要性。虽然初始的解决方案可能可以工作,但通常还有更好的方法来执行相同的任务。
最后,我意识到编写清晰、可维护和可测试的代码的重要性。这有助于确保我的代码在将来仍然有效,并允许其他人更容易地理解和使用它。