回溯法解八皇后问题

回溯的概念参见:http://blog.csdn.net/jiecooner/article/details/8673321

解释几个地方:

解空间树:

并非就是一个真正用数据结构造出来的一棵树,当然也可以真的是,不过绝大部分时候不是,因为真正的树时间复杂度和空间复杂度并不是很优的;应该是这样理解:解空间树是抽象的把问题可能的解放置在一个棵树中的叶节点,要找到这个合适的叶节点要从根结点开始深度优先搜索,在这里就可以用到回溯法带来的好处,如果在访问到一个根结点时发现由这个根结点出发的所有分支一定不会得到一个正确的叶节点时放弃这个根结点出发的所有分支的搜索,直接跳到其兄弟节点,虽然这个解空间树并非一个真的树,但要对树的基本知识有点了解,

深度优先搜索:

http://baike.baidu.com/view/288277.htm

回溯一般是用递归实现:

举个例子怎么实现:

比如用递归解决阶乘问题:

int jieshen(int n)
if(n==1)
{
	return 1;
}
return jieshen(n-1)*n;
这是阶乘,看得出这个每递归一次n减1,相当于是树的向下搜索,要想回溯那就相当于是
jieshen(n+1)*n
只是个思想;

下面看一下实现过程:

#include<stdio.h>
#include<string.h>
#define M 8
int IsTrue(int i,int j,int Q[M][M]);
void Queen(int j,int Q[M][M]);
int main()
{
	int Q[M][M];
	memset(Q,0,sizeof(Q));
	Queen(0,Q);
	getchar();
	return 0;
}
int IsTrue(int i,int j,int Q[M][M])     //这个函数是判断该皇后放置的位置和前面以放好的皇后是否有冲突;
{
	int s,t;
	for(s=i,t=0;t<M;++t)
		if(Q[s][t]==1&&t!=j) return 0; 

	for(t=j,s=0;s<M;s++)
		if(Q[s][t]==1&&s!=i) return 0;

	for(s=i-1,t=j-1;s>=0&&t>=0;s--,t--)
		if(Q[s][t]==1) return 0;

	for(s=i+1,t=j+1;s<M&&t<M;s++,t++)
		if(Q[s][t]==1) return 0;

	for(s=i-1,t=j+1;s>=0&&t<M;s--,++t)
		if(Q[s][t]==1) return 0;

	for(s=i+1,t=j-1;s<4&&t>=0;s++,--t)
		if(Q[s][t]==1) return 0;

	return 1;
}
void Queen(int j,int Q[M][M])
{
    int i,k;
	if(j==M)                 //递归结束条件
		{
			for(i=0;i<M;++i)
			{
				for( k=0;k<M;++k)
				{
					printf("%d ",Q[i][k]);
				}
				printf("\n");
			}
			printf("\n");
			return;
		}
		for(i=0;i<M;++i)
		{
			if(IsTrue(i,j,Q))      //这一步很重要,在搜索过程中减枝
				{
					Q[i][j]=1;
					Queen(j+1,Q);
					Q[i][j]=0;    //回溯
				}
		}
}



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值