算法浅谈:DFS

来源:互联网 发布:安娜baby淘宝店 编辑:程序博客网 时间:2024/06/04 18:42

今天我想给大家说一下DFS算法,DFS(Depth First Searching)是一种基于递归的算法,其中文名为深度优先搜索算法,那么我们先来通过一个简单的例子了解一下DFS算法的工作原理。
我们假定如下一个无向图:
无向图V1
我让你求一条A1到A4的路径。
这很好求吧,我们从A1出发,考虑它的邻接点A2(注意这是一个无向图),那么从A2下去就可以到达A4,因此我们得出一条路径A1->A2->A4。
那么我换一种问法。
我让你求所有从A1到A4的路径呢?
(事情似乎变得有趣了起来)
那么你可能就会想,那我就可以考虑A1所有的邻接点啊,然后往下走,走不通再从A1重新走啊。
对,这就是DFS算法的本质,回溯。
我们再假定如下一个无向图:
无向图2
可以看到我把A3到A5的路给抹掉了,那么在邻接点搜索当中,A1->A2->A4和A1->A3->A4都是两条走得通的路,但是A1->A5,这条路到不了A4,就歇菜了。
A1->A5正是我们上面所说的走不通的路
在计算机中实现无向图需要用到数据结构的知识,考虑到读者初学算法知识,不一定知道典型的数据结构,因此我们先略过不讲。
那么我们来看几道经典的DFS问题。
1.八皇后问题
八皇后问题是此前每日一题曾经出现过的题目,用到了DFS算法,现在我对八皇后问题中的DFS思想进行简单的讲述。
我们进行模拟落子,首先在第一行的i 1  列放下一个皇后,然后判断是否有冲突,没有冲突则在第二行的i 2  列放下一个皇后,判断是否有冲突。一直到第n行的第i n  列,其中i 1 ,i 2 ,,i n  1,2,,n 的一个自然排序。
那这里是怎么用到DFS算法的呢?
DFS的算法就是先从起点开始尝试走一条路,走不通就回来换另一个邻接点继续走。
在八皇后问题中,我们如果要确定一种解法,就相当于我们要在棋盘上走一条八皇后不会冲突的路。那么我们的起点是第一行的某一列,开始往第二行的某一列去走……一直到第n行的某一列,如果走不通,回到第一行,换一个起点,继续走。
这种运用DFS算法的代码中,谁是谁的邻接点呢?
此处不能叫邻接点了,应该叫邻接行,因为棋盘上相邻两行之间都是邻接的,因此可以说第2行是第1行的邻接行,第3行是第2行的邻接行……一直到第n行是第n-1行的邻接行。
因此我们的棋盘可以抽象成一个具有n个起点的无向图。
2.加法拆分问题
这个是国庆大礼包里面的一个题目,大致就是,给你一个正整数n,你要输出将n拆分成加数不小于2不大于n的加法等式。(其中加数均为正整数)
例子:
n=7的时候
7=1+1+1+1+1+1+1
7=1+1+1+1+1+2
7=1+1+1+1+3
7=1+1+1+4
7=1+1+5
7=1+6
7=1+1+1+2+2
7=1+1+2+3
7=1+3+3
7=3+4
等等
那这道题怎么做?
首先我们知道,最容易找到的等式是n个1相加等于n
那么我们假设加数的个数为k
因为2≤k≤n
因而我们可以以k为目标开始搜索。
k=2的时候,我们设n=a+b,a=1开始
那么k=2搜索结束的时候,就是a>b的时候
k=3的时候n=a+b+c,搜索结束的时候就是a>n3  的时候(默认a为最小数,因为a大了之后,会和前面的式子重复,比如7=2+2+3和7=3+2+2是一个式子,但是这个时候a已经大于了a>n3  ,因此如果不限定a为整个式子里的最小数,就会有重解)
那每次搜索的时候,退出递归的条件就是a+b+c+d+……=n
不然的话就回溯到a继续搜,对于当前a如果都没有解,则a++,直到a>nk  
那么这个搜索和八皇后的尝试放皇后的方法几乎是一样的,请大家尝试理解。
小结:
DFS算法是递归的一种体现,就是让计算机帮助你模拟循环(使用递归),从最初的起点出发,找到最终的路。DFS算法最经典的运用是用来走迷宫,因为你的起点只有一个,但是迷宫的路有很多条,其中有一些是死胡同,那么我们先开始一步一步走(递归),发现死胡同(DFS已经到达了尽头,但判断出不是终点),回到起点(回溯),重新走没有走过的路(DFS重新向深处搜索),直到发现通往终点的路(DFS搜索到达尽头,而且发现尽头恰好是终点)。如果通往终点的路不止一条,大家就可以用DFS算法将整个迷宫的路都走一遍,直到找到所有通往终点的路。
迷宫这个例子我觉得是很好理解的,想想小时候是怎么用牙签或者手指代替你来走迷宫,你是否找不到路就回去起点重新走了呢?(当然迷宫问题有更好的智能算法,此处不展开)
——KarK.Li
——2017.10.14
我的博客中的N皇后问题解法

原创粉丝点击