【数据结构】递归法解决八皇后问题

注意
二维数组为数组指针,作为函数参数必须有第二维的值。
如果是主调函数是指针数组,那么函数参数可以直接是二级指针。
如果主调函数是二级指针,函数参数为二级指针。
二级指针做输入的三种情况

  1. 数组指针/二维数组做输入 int (*p)[3]或者int p[2][3]
  2. 指针数组做输入 int* p[];
  3. 二级指针作输入 int **p;

如何实现退出第7行后 第7行数据清零 通过将原来的矩阵复制到一个新矩阵中 然后输出的是复制的矩阵 没有对输入的矩阵值进行更改

#include <stdio.h>

int count = 0;	//用这个变量来记录有多少种解法

/***************************************
*函数功能:对第row行,第j列的元素进行判断
*	传入的参数:int row	(行数)
*				int j   (列数)
*				(*chess)[8] 棋盘的数据
*	返回值:为 1 表示这个位置合适存放
*			为0 表示不合适
****************************************/

int isok(int row, int j, int(*chess)[8])
{
	int i, k, flag1 = 0, flag2 = 0, flag3 = 0, flag4 = 0, flag5 = 0;
	//对j列进行判断
	for (i = 0; i < 8; i++)
	{
		if (*(*(chess + i) + j) != 0)
		{
			flag1 = 1;
		}
	}
	//对左上方进行判断
	for (i = row, k = j; i >= 0 && k >= 0; i--, k--)
	{
		if (*(*(chess + i) + k) != 0)
		{
			flag2 = 1;
		}
	}
	//对右上方进行判断
	for (i = row, k = j; i >= 0 && k < 8; i--, k++)
	{
		if (*(*(chess + i) + k) != 0)
		{
			flag3 = 1;
		}
	}
	//对左下方进行判断
	for (i = row, k = j; i < 8 && k >= 0; i++, k--)
	{
		if (*(*(chess + i) + k) != 0)
		{
			flag4 = 1;
		}
	}
	//对右下方进行判断
	for (i = row, k = j; i < 8 && k < 8; i++, k++)
	{
		if (*(*(chess + i) + k) != 0)
		{
			flag5 = 1;
		}
	}
	if (flag1 || flag2 || flag3 || flag4 || flag5)
	{
		return 0;
	}
	return 1;
}

/*****************************************************************
*函数功能:对八皇后进行排列组合。
*		传入的参数:int row (行号)
*					int n (列)
*					(*chess)[8](棋盘的数据)
*		无返回值:
******************************************************************/
void print_array(int(*chess)[8])
{
	int i, j;
	for (i = 0; i < 8; i++)
	{
		for (j = 0; j < 8; j++)
		{
			printf("%d ", chess[i][j]);
		}
		printf("\n");
	}
	printf("\n");
}
void Queen_Position(int row, int n, int (*chess)[8])
{
	int chess2[8][8];//栈变量
	int i, j;

	//把数据复制到局部的chess2中
//每次更改的都不是传进来的矩阵
//复制了一个新的矩阵
	for (i = 0; i < 8; i++)
	{
		for (j = 0; j < 8; j++)
		{
			chess2[i][j] = chess[i][j];
		}
	}

	//进行排列,并递归调用
	if (row == 8)
	{
		printf("%d种组合\n", count);
		for (i = 0; i < 8; i++)
		{
			for (j = 0; j < 8; j++)
			{
				printf("%d ", chess2[i][j]);
			}
			printf("\n");
		}
		printf("\n");
		count++;
	}
	else
	{
		for (i = 0; i < n; i++)
		{
			if (isok(row, i, chess2))
			{
				for (j = 0; j < 8; j++)
					*(*(chess2 + row) + j) = 0;	 //注意:这要清零
				*(*(chess2 + row) + i) = 1;
				//print_array(chess2);
				Queen_Position(row + 1, n, chess2);	//满足条件进行递归调用
			}
		}
	}
}


int main(void)
{
	int chess[8][8];
	int i, j;
	for (i = 0; i < 8; i++)
	{
		for (j = 0; j < 8; j++)
		{
			chess[i][j] = 0;
		}
	}
	Queen_Position(0, 8, chess);
}


思想:先在第一行放一个值,遍历第二行可能的位置,遍历第三行可能的位置。。。。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值