浅谈dfs深度优先搜索(基于啊哈算法)

//
//  main.c
//  啊哈 DFS
//
//  Created by 姜凯文 on 2018/6/4.
//  Copyright © 2018年 姜凯文. All rights reserved.
//

#include 
int a[10], book[10], n;//此处特别说明下:C语言的全局变量在没有赋值前默认为0,因此这里的book数组无需全部再次赋初值0
//step代表现在在第几个盒子前面
void dfs (int step) {
    int i;
    if (step == n+1) {
        //如果站在第n+1个盒子前面,则表示前n个盒子已经放好扑克牌
        //输出一种排列(1~n号盒子中的扑克牌编号)
        for (i = 1; i <= n; i++) {
            printf("%d", a[i]);
        }
        printf("\n");
        return;//返回之前的一步(最近一次调用dfs函数的地方)
     }
    //此时站在第step个盒子面前,应该放那张牌呢
    //按照1,2,3。。。n的顺序一一尝试
    for (i = 1; i <= n; i++) {
        //判断扑克牌i是否在手上
        if (book[i] == 0) {
            //开始尝试使用扑克牌
            a[step] = i;//将i号扑克牌放入第step号盒子中
            book[i] = 1;//将book[i]等于0表示i号扑克牌在手上
            
            //第step个盒子已经放好了扑克牌,接下来需要走到下一个盒子前面
            dfs(step+1);//这是通过函数的递归调用实现的(最近调用自己)
            book[i] = 0;//这是非常重要的一步,一定要将刚才尝试的扑克牌收回,才能进行下一次尝试
        }
    }
    return;
}
int main(int argc, const char * argv[]) {
    scanf ("%d", &n);//输入时要注意n为1~9之间的整数
    dfs(1);//首先站在1号小盒子前面
    return 0;
}

上面是原样的书上的代码,下面我已输入n3来进行一次模拟

首先,我们输入n=3,这意味着这我们要对123进行全排列(模拟到书中的场景就是有3个小盒子),在我们读入3后,函数调用参数为1,接下来就开始模拟。

第一个盒子,读入1,然后我们在book数组中把1去掉,又一次调用,第二个盒子放入2(按顺序123来使用但是1已经被使用了),接着再次调用,第三个盒子中被放入3(同上,12,已经被放入)。

接下来有一个注意点,我们判断条件是n+1而不是n,所以我们要再往前到不存在的第四个盒子,此时判断错误打印第一条123并返回,此时返回到上一次使用dfs的地方,也就是在第三个盒子那里,我们将3收回,但是for循环已经结束,此时我们又要进行一次返回(这一次我们只是收回了3

这一次返回我们回到了第二个盒子(收回了2),这是循环到3的位置,正好将3放入,继续调用到了盒子3前面,此时for循环是从1开始的(切记,这是新使用的),正好将我们手上的2放入,又到了盒子4,于是打印132,然后返回到盒子3(收回2),执行for循环但三不在我们手里于是再返回到盒子2,收回盒子2中的3但这个for循环又结束了,于是再返回(此时我们手上有32

返回到盒子1了(收回1),执行for循环,放入2,接下来就是重复上面的步骤。

大概就这样,我可能描述的不是很清楚,因为有很多重复的话,希望最好还是对照着书来看。

————我是太阳骑士索拉尔,愿太阳永照心中


你可能感兴趣的:(算法&&数据结构)