C语言回溯法之n皇后问题清晰注释

回溯法之N皇后问题

            • 回溯法通俗诠释
            • 回溯法框架描述(无递归)
            • n皇后的C语言代码

回溯法通俗诠释

手撕算法之回溯法:
回溯法,记得大二学这个算法的时候,哎,原来这么简单!然后去做题的时候真的是一脸懵B,这个回溯法劝君一定要找几十道题好好练一练,这样才能手撕算法,不然,你就等着被撕吧!好了,扯远了,回溯,就是往回查找,大家都懂,这类问题和树的遍历是很像的,解决的问题几乎全是一个样的:我有n中选择,每种选择下面又有好多选择,然后下面的下面又有很多选择,就这样。。。。。人脑想着选择就很多很复杂,但电脑不一样,我就让电脑从第一种选择搞到最后一种选择,按照n级子树遍历完之后,遍历n-1级子树的规律,直到1级。。。很抽象,写着我也很抽象,,,不碍事,多练习几道题就知道了

回溯法框架描述(无递归)

这是一个代码框架,回溯法模式很固定,是可以直接套用的
输入正整数参数n,m(n>=m)
i=1;a[i]=<元素初值>;
while(1)
{
for(g=1,k=i-1;k–)
if(<约束条件1>) g=0;//g是标志
if(g&&<约束条件1>)
printf(a[1:m]);
if(i {i++;a[i]== <取值点>;continue;}
while(a[i ]== n&&i>1)i–;
if(a[i] == n&& i== 1) break;
else a[i]=a[i]+1;
}

n皇后的C语言代码

这里以四皇后为例,准备:一个大小为四的一维数组,用来存储位置,如a【3】=2,表示在第三行皇后放在第二个位置,这样用一维数组就可以表示每一行皇后的位置

i=1;
a[i]=1;//初始化,从第一行第一个位置开始
while(1)
{
g=1;//标志某个位置是否能放,默认能放
for(k=i-1;k>=1;k--)//看看某一行前面那几行中的皇后位置是否跟这个i行的这个位置冲突
if(a[i]==a[k]||abs(a[i]-a[k]==i-k)
{g=0;break;      //若有冲突,标志置为零
}
if(g&&i==4)//若没有冲突,则有两种情况,一:到达最后一行,得出结果,子树完成遍历,等待回溯操作
printf(a[i:4);//简写了
if(i<4&&g){i++;a[i]=1;continue;}//二:没有到达最后一行,进行下一行的操作,不用回溯
while(a[i]==4&&i>1)i--;//完成遍历后的回溯操作,核心操作
if(a[i]==4&&i==1)break;//回溯完全标志,结束程序
else a[i]=a[i]+1;}//从未遍历完成的哪一行的后一个位置继续操作


你可能感兴趣的:(回溯算法)