详细注解八皇后问题

原创 2012年03月23日 09:52:07

网上八皇后问题的代码一大把,可是“回朔递归”还是理解的不好!

这里是我一步步写出的代码和详细的注释,解释了这个问题的解决用到的“回朔和递归”体现在哪里和怎么体现的两个问题,相信看了之后,对这个问题的解决原理会有深刻的理解的。


如下:

#include <iostream>
#include <stdlib.h>
using namespace std;

#define QUEUE 8  //定义皇后的个数

int queues[QUEUE];//表示一个QUEUE*QUEUE的棋盘,其值queues[i] = 第i个皇后的放置位置,初始值为-1,程序中略去了初始化
		

static int sum = 0;//记录解的个数

bool canPlace(int k, int i)
/*
*用来判定第k个皇后能不能放置在第k行的i位置上。
*因为每行只能放置一个皇后是肯定的事情,所以8个皇后必然是每行放置一个,而我们放置皇后的时候是第i个放置在第k行的。这样给出两个参数即皇后编号k和欲放置位置即可
*k既代码行号,又代表皇后的编号
*/
{
	for( int j = 0; j < k; j++)
	/*
	*这个循环的范围是[0,k)而不是[0,QUEUE)
	*因为对于canPlace函数来说,它的任务是判定第k个皇后能不能放置在第k行的第i列即可以类,此时[k+1,QUUE)都还没有放置皇后
	*因此没有必要对其进行判定。
	*很显然对于这样的判定任务使用循环是正常的策略
	*/
	{
		if( abs(queues[j]-i) == abs(k-j) || queues[j] == i)
		/*
		*abs(queues[j]-i) == abs(k-j)是判定第k个皇后放置在第k行的第j列时,其对角线上有没有已经放置皇后。
		*queues[j] == i是判定第k个皇后放置在第k行的第j列时,该行有没有放置皇后。
		*/
			return false;
	}
	return true;
}
void printSolution()
{
	cout << sum << " solution is: " << endl;
	for( int i = 0; i < QUEUE; i++)
		cout << "queues[" << i << "] = " << queues[i] << endl;
	
}
void queueSolution(int k)
{
/*
*这里传入了一个参数,前面有说k的含义,既代表行号,又代表皇后的编号。
*使用该函数时,传入参数k=0,表示第一个皇后放置在第一行
*这是我们开始解八皇后问题的起点,即在第一行试着放置第一个皇后。
*这个函数的任务是一个放置好一个皇后,然后递归
 */
	for( int j = 0; j < QUEUE; j++)
	/*
	*这个循环是“体现和实现回朔的关键”。用来判定欲放置在第行的第k个皇后能不能放置在第k行的第j列。
	*传入参数是k,k既代表行号,又代表皇后的编号。就表示尝试第k行能不能放置第k个皇后,如果成功放置,再去放置第k+1个皇后
	*而这个循环则是对列的遍历,即尝试应该放置在第k行的第k个皇后能不能放置在这行的第i列上。通过这个循环就可以得到所有的i值
	*而当第k行的第k个皇后顺利(暂时顺利)放置在第i列(第一个i值)时,else	queueSolution(k+1);代码引发递归调用,此时
	*for循环暂停,转而程序跳转到递归的queueSolution函数又进行这个过程。
	*现在假设这个过程执行完毕,那么应该回到这个循环继续执行,即继续寻找适合的i值。当嵌套调用顺利的结束递归时,那么就表示已经找到了一个解决方案
	*此时for循环的继续运行是继续寻找另一个解决方案;当嵌套调用没有顺利结束递归时,那么就表示这个暂时顺利的i值是无效的,此时这个for循环的继续运行
	*是继续寻找正确的解决方案。这里我用了“继续”两个字描述为第k行的第k个皇后寻找适合的i位置的过程,这“回朔”的体现:嵌套以暂停循环进而深入执行,然后又返回朔到循环继续执行
	*/
	{
		if (true == canPlace(k,j))
		{
			queues[k] = j;
			if(k == QUEUE-1)//皇后全部放置好了,此时找到了一个解决方法
			{
				sum++;
				printSolution();
				cout << endl;
			}
			else	queueSolution(k+1);//递归,不管递归是否成功,都会回朔到for循环继续执行,所以这个函数可以将所有的解方案找出来
		}
	}
}
int main(int argc, char ** arg)
{
	queueSolution(0);
	return 0;
}
	

另外,8皇后的解有92种。


相关文章推荐

八皇后问题详细推导(递归和非递归,Go语言实现)

回溯法解八皇后问题(递归和非递归,Go语言实现)   问题重现: 在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法?如果问...
  • WAPWO
  • WAPWO
  • 2013年05月20日 21:24
  • 1191

Java常用算法——搜索(dfs) & 回溯(全排列、八皇后、分苹果问题的详细解析)

dfs & 回溯(1).定义 深度优先搜索算法(英语:Depth-First-Search,简称DFS)是一种用于遍历或搜索树或图的算法。沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点v...

八皇后问题的C++实现

  • 2017年09月23日 08:39
  • 446KB
  • 下载

八皇后问题

  • 2015年12月14日 16:22
  • 119KB
  • 下载

回溯算法(BackTracking)--八皇后问题

0) 回溯算法: 回溯算法也算是遍历算法的一种,回溯算法是对Brute-Force算法的一种改进算法,一个典型的应用是走迷宫问题,当我们走一个迷宫时,如果无路可走了,那么我们就可以退一步,再在其他的...

八皇后问题

  • 2015年07月07日 18:13
  • 36KB
  • 下载

八皇后问题的C语言程序

  • 2014年09月12日 17:14
  • 516KB
  • 下载

八皇后问题详解(最短代码)

八皇后问题算法分析: 分析1:八皇后由一个64格的方块组成,那么把八个皇后放入不考虑其他情况利用穷举法,有8^64种 可能。 分析2:显然任意一行有且仅有1个皇后,使用数组queen[0->7]...

北邮数据结构 八皇后问题

  • 2014年01月28日 09:20
  • 3.66MB
  • 下载

八皇后问题

  • 2014年03月06日 10:48
  • 758KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:详细注解八皇后问题
举报原因:
原因补充:

(最多只允许输入30个字)