N皇后递归回溯流程还是未懂


#include <stdio.h>

const int N=99;
int a[N];    //a[i]表示第i行上的皇后放于a[i]列上,假设a[3]=7
int cnt,n=4; 

bool check(int x,int y){
    for(int k=1;k<=x;k++){
        if(a[k]==y)    return false;
        if(k+a[k]==x+y)    return false;
        if(k-a[k]==x-y)    return false; 
        
        //if(a[i]==y || i+a[i]==x+y || i-a[i]==x-y)    return false;
    }
    return true;
}
void dfs(int row){    //表示第row行皇后放于何处 
    if(row==n+1){
        //产生了一组解
        cnt++; 
        return;
    }
    for(int i=1;i<=n;i++){
        if(check(row,i)){
            a[row]=i;
            dfs(row+1);
            a[row]=0;
        } 
    }
}
 
int main(void){
    dfs(1);
    printf("%d",cnt); 
    return 0;
}

img

第一次执行把皇后Q1放在了第1行第1列,第二次执行把皇后Q2放在了第2行第3列,第三次执行因为第三行都是Q1和Q2的攻击区域,程序是如何回溯把Q2放在第2行第4列

参考 回溯法(八皇后问题)及C语言实现_yuer_xiao的博客-CSDN博客_八皇后问题回溯法        回溯法,又被称为“试探法”。解决问题时,每进行一步,都是抱着试试看的态度,如果发现当前选择并不是最好的,或者这么走下去肯定达不到目标,立刻做回退操作重新选择。这种走不通就回退再走的方法就是回溯法。回溯VS递归        很多人认为回溯和递归是一样的,其实不然。在回溯法中可以看到有递归的身影,但是两者是有区别的。        回溯法从问题本身出发,寻找可能实现的所有情况... https://blog.csdn.net/yuer_xiao/article/details/82714734

首先你别纠结回溯不回溯的,回溯只是结果,根本没有回溯这个过程。
因为用的是递归,而不是简单的循环,所以每进入一层,之前所有调用过的函数和变量其实还在内存里,没有丢失
你可以理解为很多树状的分岔路,程序会沿着所有的路向前走,每遇到一个分叉不会直接走进去而是先留一份拷贝,然后往里走
如果路可以一直走通,走到终点就形成一个解
如果走不通,丢弃当前结果,退出函数,那么程序自动从上一层节点继续找新的路
这就是所谓回溯

看了猫猫老师的视频已弄懂递归和回溯了