8皇后非递归求解


八皇后问题是一个比较经典的问题。

问题如百度百科上



网上递归版本的八皇后解法很多。非递归版本相对较少。

事实上,递归版本和非递归版本原理类似。非递归版本借用栈来实现深度搜索,根据栈的元素个数来确定是否回溯的。

先贴代码~(C++  运行环境 dev C++ 5.11 win10 )

#include <stdio.h>
#include <memory.h>
//http://paste.ubuntu.com/23583833/
typedef struct myStack{
	int a[100];
	int top;
}myStack;

void init(myStack *s){
	s->top = -1;
}

bool isempty(myStack *s){
	return s->top==-1;
}

int size(myStack *s){
	return s->top+1;
}

void pop(myStack *s){
	if(!isempty(s))
		s->top--;
}

void push(myStack *s,int data){
	s->a[++s->top] = data;
}

int get(myStack *s,int index){
	return s->a[index];
}

int top(myStack *s){
	return s->a[s->top];
}

bool crash(myStack *s, int data){
	if(isempty(s))
		return false;
	int ssize = size(s);
	int state = -1;
	for(int i = 0; i < size(s); ++i){
		state = get(s,i);
		if(data==state || (ssize-i==data-state || ssize-i==state-data)){
			return true;
		}
	}
	
	return false;
}

int main(){
	myStack *s = (myStack*)malloc(sizeof(myStack));
	init(s);
	int count = 0;
	int i = 0;		
	while(i<8 || !isempty(s)){
		// note :if语句顺序不能乱。 
		if(size(s) == 8){
			// 找到结果 ,打印输出 
			for(int p=0; p<8; ++p)
				printf("%d ",get(s,p));
			printf("\n");
			// 结果总数 +1 
			count++;
			pop(s);
			i = top(s) + 1;//下一个待找的位置 
			pop(s);
			//如果当前的位置正确,那么该行不会出现其他位置满足条件了,所以pop两次。 
		}else if(i==8){
			// 判断是否超过棋盘范围 
			i = top(s) + 1;
			pop(s);
		} else if(crash(s,i)){
			//如果冲突,那么就去找下一个位置 
			++i;
		}  else {
			//压栈 ,dfs 
			push(s,i);
			i = 0;
		}
	}
	printf("共计%d种可能!",count);	
	free(s);
	return 0;
} 


首先定义了myStack栈结构,其中top为栈顶标记。后面定义了栈的基本操作,如判栈空,取栈顶元素,取第i个元素(i从0开始),栈元素个数,压栈,出栈等。

crash判断当前位置是否与之前冲突。

判断条件

(ssize-i==data-state || ssize-i==state-data)

判断了斜线攻击的情况。



主函数里面提供了深度优先搜索的方法。其中需要注意的是,if条件顺序不能颠倒,否则可能找不到while循环的出口,导致死循环。(捂脸,第一次运行的时候i==8和crash(s,i)顺序颠倒了,导致i一直往上加而程序不能终止)


程序运行截图:


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

A.Star

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值