N皇后问题(回溯法递归)
1 /********************************************************************************** 2 *Name: N皇后问题 3 *Date: 2022.01.17 4 *Author: 吕辉 5 *Description: N皇后问题要求在一个 N * N 格的棋盘上放置N个皇后,使其互不攻击。 6 * 按规则互不攻击的约束条件为,任意两个皇后不能处于同一行、同一列或同一对角线上, 7 * 现要求给出满足约束条件的所有棋盘布局。 8 ***********************************************************************************/ 9 #define _CRT_SECURE_NO_WARNINGS 10 #include <stdio.h> 11 #include <stdlib.h> 12 #include <math.h> 13 #include <time.h> 14 15 /*孩子兄弟表示法的抽象数据类型*/ 16 typedef struct node 17 { 18 int data;/*存储皇后的横坐标*/ 19 struct node* fristchild; 20 struct node* nextsibling; 21 struct node* parent; 22 }Node, *Tree; 23 24 void Print(Tree A, int n); 25 int Place(Tree A, int layer); 26 void Queen(Tree* A, int layer, int n, int* sum); 27 28 int main(void) 29 { 30 int n = 0; 31 int sum = 0; 32 clock_t start; 33 clock_t finish; 34 Tree A = NULL; 35 36 printf("请输入棋盘阶数:"); 37 scanf("%d", &n); 38 39 start = clock(); 40 Queen(&A, 1, n, &sum); 41 finish = clock(); 42 printf("%d阶棋盘共有%d种布局,用时%.fms\n", n, sum, (double)(finish - start)); 43 system("pause"); 44 return 0; 45 } 46 47 /********************************************** 48 * Function: Print 49 * Description: 打印符合约束条件的棋盘布局 50 * Called By: Queue 51 * Parameter : A 树的结点指针 52 * n 所在层数 53 ***********************************************/ 54 void Print(Tree A, int n) 55 { 56 while (A) 57 { 58 printf("(%d,%d) ", n--, A->data); 59 A = A->parent; 60 } 61 printf("\n"); 62 } 63 64 /*************************************************** 65 * Function: Place 66 * Description: 判断当前皇后位置是否符合约束条件 67 * Called By: Queue 68 * Parameter : A 树的结点指针 69 * layer 当前结点所在层数 70 * Return: 返回 0 表示当前皇后位置不符合约束条件 71 * 返回 1 表示当前皇后位置符合约束条件 72 ****************************************************/ 73 int Place(Tree A, int layer) 74 { 75 int prelayer = layer;/*前一行皇后所在行号*/ 76 int data = A->data;/*当前行皇后所在列号*/ 77 A = A->parent; 78 while (A) 79 { 80 prelayer--; 81 /*皇后位置在同一列或者在同一对角线上返回0*/ 82 if (A->data == data || (abs(prelayer - layer) == abs(A->data - data))) 83 { 84 return 0; 85 } 86 A = A->parent; 87 } 88 return 1; 89 } 90 91 /******************************************************** 92 * Function: Queen 93 * Description: 通过回溯法查找所有可能组合并打印 94 * Called By: main 95 * Parameter : A 树的结点指针 96 * layer 当前结点所在层 97 * n 所在层数 98 * sum 可能的组合总数 99 *********************************************************/ 100 void Queen(Tree* A, int layer, int n, int* sum) 101 { 102 int i = 0; 103 Tree P = NULL; 104 Tree Pre = NULL; 105 if (layer > n) 106 { 107 Print((*A), n); 108 (*sum)++; 109 } 110 else 111 { 112 for (i = 1; i <= n; i++) 113 { 114 P = (Tree)calloc(1, sizeof(Node)); 115 P->data = i; 116 if ((*A)) 117 { 118 if ((*A)->fristchild == NULL) 119 { 120 (*A)->fristchild = P; 121 } 122 P->parent = (*A); 123 } 124 else 125 { 126 P->parent = NULL; 127 } 128 129 if (Place(P, layer) == 1) 130 { 131 Queen(&P, layer + 1, n, &(*sum)); 132 } 133 if (Pre) 134 { 135 Pre->nextsibling = P; 136 } 137 Pre = P; 138 }/*for循环*/ 139 }/*else*/ 140 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现