递归--基于回溯和递归的八皇后问题解法

八皇后问题是在8*8的棋盘上放置8枚皇后,使得棋盘中每个纵向、横向、左上至右下斜向、右上至左下斜向均只有一枚皇后。八皇后的一个可行解如图所示:

             

   

         

             
         

   
 

           
       

     
           

 
     

       

思路

对于八皇后的求解可采用回溯算法,从上至下依次在每一行放置皇后,进行搜索,若在某一行的任意一列放置皇后均不能满足要求,则不再向下搜索,而进行回溯,回溯至有其他列可放置皇后的一行,再向下搜索,直到搜索至最后一行,找到可行解,输出。

此处可用借鉴陈海涛网易博客中的思路,不用二维数组,而采用一维数组进行回溯,参见http://www.cnblogs.com/jiayouwyhit/p/3226757.html。因为1维数组的下标即可表示行或者列,再在一维数组里面赋值,即可代表列或者行。此条件即可至少满足八皇后问题的一个条件:两个皇后不同行或者不同列。省去后文的一个步骤判断。

 

本人参考网上别人的回溯思路,写的代码如下:(注意,本代码已经在VC6.0下通过实验测试)

//8皇后问题
//基于递归的回溯算法
const int length=8;

int counter=0;

bool Check(int matrix[], int row)//检验是否合理
{
    int i=0;
    for (i=0;i<=row-1;i++)
    {
        if (matrix[i]==matrix[row] || row-i==matrix[row]-matrix[i] ||i-row==matrix[row]-matrix[i])
            return false;
    }
    return true;
}

void EightQueen(int matrix[], int row)
{
    int i=0,j=0;
    for (i=0;i<length;i++)
    {
        matrix[row]=i;
        if (Check(matrix,row) && row<=length-1)//满足要求
        {
            if (row==length-1)
            {
                ++counter;
                printf("Solution %d:\n",counter);
                for (j=0;j<length;j++)
                    printf("%4d",matrix[j]);
                printf("\n");
            }
            else
                  EightQueen(matrix,row+1);
        }
    }
}

int main(int argc, char* argv[])
{
    int matrix[length]={0};
    EightQueen(matrix,0);

    printf("We have solved the problem!\n");
    return 0;
}

 

复杂度分析:本文算法的时间复杂度为O[n^(n+1)]。比http://www.cnblogs.com/jiayouwyhit/p/3226757.html时间复杂度更高.

实际上,经过实际的实验测试,本文的算法实际上在时间上要比前面提到的算法性能要好很多。经过仔细分析,其原因在于:本文算法中对递归有一个限制条件

Check(matrix,row),即:当当前点不满足我们的约束条件时,直接就不再进行递归,因此函数void EightQueen(int matrix[], int row) 的时间复杂度会远远小于O[n^n](假如不考虑check函数自身的时间复杂度的话)。但该算法具体的时间复杂度是多少,由于有判断语句的存在,本人觉得此处无法写出具体的复杂度表达式(再一次说明本人数学功底还有待提高啊\(^o^)/~)。

posted @ 2013-07-31 11:08  jiayouwyhit  阅读(1851)  评论(0编辑  收藏  举报