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 }
复制代码

 

posted @   吕辉  阅读(44)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示