1.代码
#include <stdio.h>
#include <stdlib.h>
#include<math.h>
#include<stdbool.h>
#include<malloc.h>
/**
*Place it there,applicate?
*/
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;
}//of for
return true;
}//of place
/**
*Backbracking.
*/
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);
}//of for i
}//of if
}//of backtracking
/**
*Title:n queens<br>
*/
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);
}//of nQueen
/**
*The entrance
*/
int main(){
nQueen(5);
return 1;
}//of main
2.运行结果
3.小结
根节点:树的根节点代表问题的初始状态,即一个空的N×N棋盘。
节点表示:树中的每个节点代表棋盘的一个特定状态,即已经放置了若干个皇后的棋盘布局。每个节点可以包含一些信息,如当前已经放置的皇后的位置、剩余未放置皇后的行数等。
子节点生成:对于树中的每个节点(除叶节点外),可以通过在当前节点的基础上尝试放置一个新的皇后来生成子节点。在尝试放置新皇后时,需要确保不违反N皇后问题的规则(即不与已放置的皇后在同一行、同一列或同一斜线上)。
剪枝:如果在尝试放置新皇后时发现无法找到合适的位置(即所有可能的位置都与已放置的皇后冲突),则当前节点成为叶节点,并且不再生成新的子节点。这个过程称为剪枝。
回溯:当一个节点的所有子节点都已经被探索过,且没有找到有效的解时,算法会回溯到该节点的父节点,并继续探索其他可能的路径。
解的状态:当算法找到一个满足N皇后问题规则的节点时(即已经成功放置了N个皇后),该节点就是一个解状态。从根节点到该解状态的路径代表了一个有效的解。
优化:为了提高搜索效率,可以使用一些优化技巧来减少不必要的搜索。例如,在尝试放置新皇后时,可以先检查同一列和两条对角线上是否有冲突,以避免生成无效的子节点。
树的大小:N皇后问题的状态空间树的大小随着N的增加而急剧增长。因此,对于较大的N值,直接搜索整个状态空间树可能是不现实的。在这种情况下,需要采用更高效的搜索算法或启发式策略来找到解。