C语言八皇后问题----递归精讲

本文详细介绍了如何使用C语言解决经典的八皇后问题。通过定义8*8的棋盘和递归算法,确保每个皇后都能安全地放置在棋盘上,避免相互攻击。代码实现了放置皇后、判断安全性和输出解决方案的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C语言八皇后问题
棋盘是8*8的,所以定义一个8的宏,方便后面的使用,如果以后更改棋盘大小,也只需要更改宏定义就好了,很方便。代码如下:

#define		WIDTH		8

定义一个8*8(棋盘大小为8),值全为0的二维数组,,后面每放一个皇后,其二维数组上的值对应改变为1(0表示无皇后,1表示有皇后)。代码如下:

chessBoard[WIDTH][WIDTH] = {0};

放置皇后的原则为:每一行放置一个皇后,放置皇后的横行、竖行、45°斜行和135°斜行,都不能放置皇后了。所以你放置每一个皇后的时候,需要考虑这个皇后的竖行、45°行和135°行(肯定是一行放一个,所以横行不用考虑,肯定也是由第一行、第二行、第三行依次往后放,所以后面肯定也没有,也就不用考虑了)。判断棋盘此处是否能放置皇后的代码如下:

boolean isSafe(boolean (*chessBoard)[WIDTH], int row, int col) {
	int i;
	int j;
	//检查左斜上方是否有皇后
	for (i = row - 1, j = col - 1; i >= 0 && j >= 0; j--, i--) {
		if (chessBoard[i][j] == 1) {
			return FALSE;
		}
	}
	//检查上方是否有皇后
	for (i = row - 1, j = col; i >= 0; i--) {
		if (chessBoard[i][j] == 1) {
			return FALSE;
		}
	}
	//检查右斜上方是否有皇后
	for (i = row - 1, j = col + 1; i >= 0 && j < WIDTH; i--, j++) {
		if (chessBoard[i][j] == 1) {
			return FALSE;
		}
	}

	return TRUE;
}

如果判断的位置可以放置皇后,则,返回TRUE。不能则返回FALSE。

下面我们编写一个函数,用来把八皇后进行遍历输出。八皇后位置为1。不是八皇后则位置为0;

void showChess(boolean (*chessBoard)[WIDTH]) {
	int row;
	int col;
	static int no = 0;//静态存储类变量只执行一次,而且延长了局部变量的生命周期,直到程序运行结束以后才释放。 

	printf("第%d个解:\n", ++no);
	for (row = 0; row < WIDTH; row++) {
		for (col = 0; col < WIDTH; col++) {
			printf("%5d", chessBoard[row][col]);//遍历输出八皇后
		}
		printf("\n");
	}
}

下面就是主要的函数,用递归的方法,让八行都有皇后。对于每一行,需要依次尝试每一个位置,判断其安全性(调用上面的isSafe函数),若安全,则尝试下一行(递归)。那么何时能知到八行都有皇后了呢?当能进行到第九行(二维数组下标为8的时候),就得知其摆出了成功的八皇后,即:row >= WIDTH。然后使用前面写过的函数shouChess(),遍历输出八皇后

void chess(boolean (*chessBoard)[WIDTH], int row) {
	int col;

	if (row >= WIDTH) {
		showChess(chessBoard);
		return;
	}

	for (col = 0; col < WIDTH; col++) {
		if (isSafe(chessBoard, row, col)) {
			chessBoard[row][col] = TRUE;
			chess(chessBoard, row + 1);
			chessBoard[row][col] = FALSE;
		}
	}
}

当你递归到下一行的时候,如果八个位置都不满足,那么执行代码:chessBoard[row][col] = FALSE;
即上一行为1的皇后变为0,横行col++。之后进行判断,下一个位置是否安全。

代码输出一共有92种八皇后,但其具有对称性,所以要除于4,即92/4 = 23种八皇后。
解的情况

以上就是全部的八皇后代码,使用了递归的思想。

后面附上所有的代码(若被使用,请注明出处,谢谢配合):

#include <stdio.h>


typedef unsigned char boolean;
#define		TRUE		1
#define		FALSE		0

#define		WIDTH		8

void showChess(boolean (*chessBoard)[WIDTH]);
boolean isSafe(boolean (*chessBoard)[WIDTH], int row, int col);
void chess(boolean (*chessBoard)[WIDTH], int row);

void chess(boolean (*chessBoard)[WIDTH], int row) {
	int col;

	if (row >= WIDTH) {
		showChess(chessBoard);
		return;
	}

	for (col = 0; col < WIDTH; col++) {
		if (isSafe(chessBoard, row, col)) {
			chessBoard[row][col] = TRUE;
			chess(chessBoard, row + 1);
			chessBoard[row][col] = FALSE;
		}
	}
}

boolean isSafe(boolean (*chessBoard)[WIDTH], int row, int col) {
	int i;
	int j;
	//检查左斜上方是否有皇后
	for (i = row - 1, j = col - 1; i >= 0 && j >= 0; j--, i--) {
		if (chessBoard[i][j] == 1) {
			return FALSE;
		}
	}
	//检查上方是否有皇后
	for (i = row - 1, j = col; i >= 0; i--) {
		if (chessBoard[i][j] == 1) {
			return FALSE;
		}
	}
	//检查右斜上方是否有皇后
	for (i = row - 1, j = col + 1; i >= 0 && j < WIDTH; i--, j++) {
		if (chessBoard[i][j] == 1) {
			return FALSE;
		}
	}

	return TRUE;
}

void showChess(boolean (*chessBoard)[WIDTH]) {
	int row;
	int col;
	static int no = 0;//静态存储类变量只执行一次,而且延长了局部变量的生命周期,直到程序运行结束以后才释放。 

	printf("第%d个解:\n", ++no);
	for (row = 0; row < WIDTH; row++) {
		for (col = 0; col < WIDTH; col++) {
			printf("%5d", chessBoard[row][col]);//遍历输出八皇后
		}
		printf("\n");
	}
}

int main() {
	boolean chessBoard[WIDTH][WIDTH] = {0};

	chess(chessBoard, 0);

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值