八皇后非递归回溯算法c语言,【回溯法】八皇后问题(递归和非递归)

先贴代码,分递归回溯法和非递归回溯法

递归回溯法,代码如下:

//test.cpp : Defines the entry point for the console application.//#include"stdafx.h"#include#include

using namespacestd;int a[9] = {0};int n = 8;int count = 0;bool check(int arr[], intn)

{for (int i = 2; i <= n; ++i)for(int j = 1; j <= i-1; ++j)if (arr[i] == arr[j] || (abs(arr[i]-arr[j]) == abs(i-j)))return false;return true;

}void printQueens(inta[])

{

printf("第%d种情况:", count);for (int i = 1; i <= n; ++i)

printf("%d",a[i]);

printf("\n");

count++;

}void searchQueens8(intr)

{if (r >n)

printQueens(a);for (int i = 1; i <= n; ++i)

{

a[r]=i;if(check(a, r))

{

searchQueens8(r+1);

}

}

}int _tmain(int argc, _TCHAR*argv[])

{

searchQueens8(1);return 0;

}

非递归回溯法,代码如下:

#pragma once#include"stdafx.h"

const int N = 8;int cszStack[9];int sum = 0;inttop;voidprintQueenStack()

{

printf("No.%d:", sum);for (int i = 1; i <= N; ++i)

printf("%d", cszStack[i]);

printf("\n");

sum++;

}//k表示第k行

bool judge(intk)

{if (k == 1)return true;inti;for (i = 1; i < k; ++i)

{if (cszStack[i] ==cszStack[k])return false;if (abs(k-i) == abs(cszStack[k] -cszStack[i]))return false;

}return true;

}voidputQueen()

{

top= 1;while(top > 0)

{

cszStack[top]++; //摆放一个皇后//如果第top行的皇后没有摆放出第8列,那就一直找到它在top行的合法位置

while((cszStack[top] <= N) && (!judge(top)))

cszStack[top]++;if (cszStack[top] <=N)

{if (top ==N)

{

printQueenStack();//输出结果

}else{

top++;

cszStack[top]= 0;

}

}else{//在第top行8列全部不能放置皇后,说明前面几行的摆放不合理,所以要退回上一行

top--;

}

}

}voidinitStack()

{for (int i = 0; i <= N; ++i )

cszStack[i]= 0;

sum= 0;

top= 0;

}voidsearchQueueStack()

{

initStack();

putQueen();

}int _tmain(int argc, _TCHAR*argv[])

{//SearchQueens8(1);

searchQueueStack();return 0;

}

指导思想:

走不通,就掉头;

检查合格才继续往下走;遇到不合格就是掉头;

能进则进,不能进则换,不能换则退;

解空间:一颗树空间

扩展规则:深度优先策略

设计过程:(1)确定问题的解空间;(2)确定结点的扩展规则;(3)搜索解空间

退回到上一状态的过程叫做回溯,枚举下一个状态的过程叫做递归;

回溯就像人走迷宫,先选择一个前进方向尝试,一步步试探,在遇到死胡同不能再往前的时候就会退到上一个分支点,另选一个方向尝试,而在前进和回撤的路上都设置一些标记,以便能够正确返回,直到达到目标或者所有的可行方案都已经尝试完为止。

回溯法应用——算法说明

(1)      八皇后问题中的核心代码

遍历过程函数;check函数;

(2)      解决此类问题的核心内容

解空间树的搜索算法;估值/判断函数:判断哪些状态适合继续扩展,或者为答案状态;

递归算法框架:

int a[n];

Queens(int k)

{

if (k > n)

// 即表示最后一个皇后摆放完毕,输出结果;

else

//枚举k个皇后所有可能路径

for (int i = 下界;I <= 上界; i++)

{// 依次从列顶端开始搜索,一直到列底端,直到找到合适的位置,如果未找到,自动返回上层递归

a[k] = i;

if (check(a,k))

// 递归摆放下一个皇后Queens(k+1);

}

}

非递归算法框架:

int a[n],i;

初始化数据a[];

i = 1;

while (i > 0(有路可走)) and (未达到目标)// 还未回溯到头

{

if (i == n)

搜索到一个解,输出;// 搜索到叶结点

else

{

a[i]第一个可能的值

while(a[i]不满足约束条件且在搜索空间内)

a[i]下一个可能的值;

if(a[i]在搜索空间内)

{ 标识暂用的资源;i=i+1;} // 扩展下一个结点

else

{清理所占的状态空间;i=i-1;} // 回溯

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值