软讯网络 > 软件时空 > 软件相关 > 递归实现N皇后问题
【标 题】:递归实现N皇后问题
【关键字】:
【来 源】:http://www.cublog.cn/u/21990/showart.php?id=144236
递归实现N皇后问题
首先悲叹一下自己的数学水平:太差了。
开始学数据结构时,也是开始学C语言的时候,那时脑筋转出火花来也对递归的执行过程理解不好,更别用说用递归来解题了(当然不是解那种公式就已经是递归方式的数学题了)。为了这该死而又至关重要的递归问题,专门从图书馆借了本有递归专题的书,书上还讲了如何将一般的递归问题用非递归实现(即循环)。狠狠啃了一段时间,虽然还是有些懵懵懂懂,却也知道了递归的内部执行过程;还积累了一点点用递归解题的套路感觉。
时隔一年多,今天复习《数据结构与算法》时试图用递归实现N皇后问题,发现又掉进了云里雾里,脑瓜子转大了,出火花子了,往往在那似乎拨云见日的关键时候又迷糊了。
经过几番思索,写出了如下算法描述:
/**
* 参数n表示行n以前的皇后都各就各位了,现在在行n放一个皇后。注意n从0开始。
* 另外算法用到一个全局整型数组a,依次存放的是已安置就位的皇后所在列数,例如a[0] = * 1表示行0的皇后放在列1上。还用到一个辅助函数,用来判断在行n列i放置皇后会不 * 会导致冲突,这个判断比较简单,没有列出。
**/
int Queen(int n){
if( n == N)
return 1;//如果这是行N,那么问题已成功解决,返回1
for( int i = 0; i < N; i++){//对于行n的每一列进行尝试
if( !conflict(n, i) ){//如果行n的列i放置皇后能相安无事,则在此处放置,并递归解决行n + 1的放置问题
记录行n在列i放置了皇后;
if( Queen(n + 1) == 1)
return 1;//如果n + 1列也解决了问题,那么整个问题解决
}
}
return 0;//在行n以前的放置情况下,行n已无法放置皇后,返回0
}
与书上对比,发现完全正确,嗯,还好,算是进一步了,以后再用递归时应该不会那么吃力吧。
值得一提的是这个算法描述开始时没有在递归调用那一句加上判断,也就是if那一句以前没有,就光秃秃一个Queen(n + 1)摆那儿,事实上那时Queen没有返回值,而是void型,当然最后一句return 0也没有了。
这时会有什么结果呢?这将导致问题完全解决之后算法会继续运行。在以后的运行中第一遍是尝试在行7的下一列放置皇后,直至尝试所有的列,然后回溯尝试在行6的下一列放置皇后,.......,这样,我歪打正着地求出了所有的解,算法最终因为第一句if( n == N) return;而结束。
只不过,很遗憾地是,这些解没有被输出来,前一个解会被下一个解覆盖掉,剩下最后一个解才最终保留在了数组a中。解决办法倒是有:如果在执行过程中检查a中的元素个数,如果等于N则输出;或者检查参数n的值,如果值是7就输出a的内容,这样就能输出所有的解了。
但是,又有了新的问题:不管愿不愿意,算法只要执行就会一厢情愿地算出所有解,这样会导致函数执行N!次,而每次函数执行的开销是N^2(首先for循环N次,for里面判断是否冲突时还一个N次),因此最终的时间开销是O(N^2 * N!),这个开销可不好玩。
【相关文章】
没有相关文章