8皇后非递归求解

来源:互联网 发布:南京极目大数据面试 编辑:程序博客网 时间:2024/05/12 00:09


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

问题如百度百科上



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

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

先贴代码~(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一直往上加而程序不能终止)


程序运行截图:


 

0 0
原创粉丝点击