八皇后问题(C语言代码——小甲虫数据结构)

经典八皇后问题,主要用到的是递归回溯,网上小甲虫的源代码我没找到,这儿给贴一个吧。

//小甲虫数据结构之八皇后问题

#include <stdio.h>
#define		CHESS_ROW           8                //棋盘行数
#define     CHESS_COLUMN        8                //棋盘列数

int count=0;

int notDanger(int row, int j , int (*chess)[CHESS_COLUMN])
{
	int i, k;
	int flag1=0,flag2=0,flag3=0,flag4=0,flag5=0;
	
	//判断列方向是否有危险
	for(i=0; i <CHESS_ROW; i++)
	{
		if(*(*(chess+i)+j)!=0)
		{
			flag1 = 1;
			break;
			//	return 0;
		}
	}
	
	//判断左上方
	for(i=row, k=j; i>=0&&k>=0; i--,k--)
	{
		if(*(*(chess+i)+k)!=0)
		{
			flag2 = 1;
			break;
			//return 0;
		}
		
	}
	//判断右下方
	for(i=row, k=j; i<CHESS_ROW && k< CHESS_COLUMN ; i++,k++)
	{
		if(*(*(chess+i)+k)!=0)
		{
			flag3 = 1;
			break;
			//return 0;
		}	
	}
	//判断右上方
	for(i=row, k=j; i>=0 && k<CHESS_COLUMN; i--,k++)
	{
		if(*(*(chess+i)+k)!=0)
		{
			flag4 = 1;
			break;
			//	return 0;
		}	
	}
	//判断左下方
	for(i=row, k=j; i<CHESS_ROW && k>=0; i++,k--)
	{
		if(*(*(chess+i)+k)!=0)
		{
			flag5 = 1;
			break;
			//return 0;
		}	
	}
	
	if(flag1|| flag2|| flag3 ||flag4 ||flag5)
		return 0;
	else
		return 1;
	
}


// row:起始行
// n: 列数
// (*chess)[8] 棋盘中每行的向量
/*
 * 八皇后递归算法,只使用了一个棋盘。
 * 每次摆放到该行的最后一列时,
 * 在返回上一行前先清空上一行上面
 * 摆放的棋子。则不需要每次调换都
 * 生成棋盘记录当前棋盘状况。
 */
void eightqueen(int row, int (*chess)[CHESS_COLUMN])
{
	int chess2[CHESS_ROW][CHESS_COLUMN];
	int i, j, flag;	
	
	for(i=0;i<8;i++)//初始化棋盘
		for(j=0;j<8;j++)
			chess2[i][j] = chess[i][j];
		
		if(CHESS_ROW == row)
		{
			printf("第%2d次的结果是:\n", count+1);
			
			for(i=0;i<CHESS_ROW;i++)//输出棋盘
			{	
				for(j=0;j<CHESS_COLUMN;j++)
					printf("%d ",*(*(chess2+i)+j));

				printf("\n");
			}	
			count++;
			return;
		}
		else
		{
			for(j=0; j<CHESS_COLUMN; j++)
			{
				flag = notDanger(row, j , chess2);
				if(1==flag)
				{
					for(i=0; i<8; i++)
						*(*(chess2+row)+i) = 0; 
					
					*(*(chess2+row)+j) = 1;
					eightqueen(row+1, chess2);	
				}			
				
			}
			
		}
		
		
}

void main(void)
{
	int chess[CHESS_ROW][CHESS_COLUMN];
	int i, j;
    
	for (i = 0; i < CHESS_ROW; i++) {
		for (j = 0; j < CHESS_COLUMN; j++) {
			chess[i][j] = 0;
		}
	}
	
        eightqueen(0, chess);
        return;	
}

答案已经说了,92种,不过好像由于缓冲区的原因,所有的排列不能一次性显示,所以想看过程的可以单步调试。

在调用eightqueen的时候会重新建立一个数组,对递归来说,这样会很占内存,稍后会补充改进的方法。

//方法two
void eightqueen(int row, int (*chess2)[CHESS_COLUMN])
{
	//	int chess2[CHESS_ROW][CHESS_COLUMN];
	int i, j, flag;	
	
	/*	for(i=0;i<8;i++)//初始化棋盘
	for(j=0;j<8;j++)
	chess2[i][j] = chess[i][j];
	*/		
	if(CHESS_ROW == row)
	{
		printf("第%2d次的结果是:\n", count+1);
		
		for(i=0;i<CHESS_ROW;i++)//输出棋盘
		{	
			for(j=0;j<CHESS_COLUMN;j++)
				printf("%d ",*(*(chess2+i)+j));
			
			printf("\n");
		}	
		count++;
		//对本行进行清空
		for(i=0; i<8; i++)
			*(*(chess2+row-1)+i) = 0; 
		return;
	}
	else
	{
		for(j=0; j<CHESS_COLUMN; j++)
		{
			flag = notDanger(row, j , chess2);
			if(1==flag)
			{
				for(i=0; i<8; i++)
					*(*(chess2+row)+i) = 0; 
				
				*(*(chess2+row)+j) = 1;
				eightqueen(row+1, chess2);	
			}			
			
		}
		
	}

// 遍历完这一行(参数row)之后, 对这一行进行清空
// 这段代码可以对chess进行逐行的清空

// 上面的代码只是对8-1行进行了清空,而外层的循环进行的时候(比如调用row行的时候)
//在调用完之后,chess中的第row行是有数据的,所以要把这行清空才能用于后面判断其他位置是否有效
	if (row > 0) 
	{                //没有到首行,则清空上一行
      		for(i=0; i<8; i++)
			*(*(chess2+row-1)+i) = 0; 
    }
	
	
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值
>