Conversation
将二分查找拆分出各个章节
Update README.md & LOGO
liweiwei1419
left a comment
There was a problem hiding this comment.
整体没有大问题,深度优先搜索在开始章节能期待够给读者在脑海里建立「深搜」的思想。
看看能不能制作更生动的图形,或者在网上找一下。达到的效果是,读者一想到深搜,就想到你说的「一条道走到底」,我就得就很成功了。
| @@ -0,0 +1,27 @@ | |||
| # 深度优先搜索算法 | |||
|
|
|||
| **深度优先搜索**(Depth-First-Search, DFS)是一种用于遍历或搜索树或图的算法,与深度优先搜索密切相关的是**广度优先算法**与**回溯算法**。 | |||
There was a problem hiding this comment.
「回溯算法」本质上行还是一种「深度优先搜索」的算法,这个算法强调了使用一份状态变量去搜索整个状态空间。与「广度优先搜索」还是不太一样的,可以单独提一句,不用放在和「广度优先遍历」一块写。
其实,在适当的地方(或者是后面的例题里)。树中因为不存在环,因此在遍历的过程中无需记录哪些节点已经访问过。但是在图中,就不一样,一般而言需要使用 visited 数组或者哈希表记录已经访问过的节点。
|
|
||
| **深度优先搜索**(Depth-First-Search, DFS)是一种用于遍历或搜索树或图的算法,与深度优先搜索密切相关的是**广度优先算法**与**回溯算法**。 | ||
|
|
||
| 深度优先遍历会 遵循**一条路走到黑,不撞叶子节点不回头**的原则。 |
There was a problem hiding this comment.
这里空格没有必要。
另外这句话其实很突出地说明了「深度优先遍历」的思想,建议放在文章的开头。「叶子节点」有点特殊,前面得先说,在「树形问题」里,「叶子节点」这个概念出现才不会很突兀,「叶子节点」是一条路径的尽头,「深度优先遍历」的思想是直到走到尽头的时候才会回头。
|
|
||
| 深度优先遍历会 遵循**一条路走到黑,不撞叶子节点不回头**的原则。 | ||
|
|
||
| 下图以二叉树为例讲解 DFS 算法的基本思想。DFS 算法会沿着二叉树的一条路搜索,直至走到叶子节点。当搜索至叶子节点时,会进行**回溯**,回溯到父节点,并继续父节点的另一个子节点。 |
There was a problem hiding this comment.
「回溯」这个词其实并不是那么口语化,事实上,它有专门的含义(上面的意见也提到了),这里直接写「回头」更直接。
|
|
||
| 下图以二叉树为例讲解 DFS 算法的基本思想。DFS 算法会沿着二叉树的一条路搜索,直至走到叶子节点。当搜索至叶子节点时,会进行**回溯**,回溯到父节点,并继续父节点的另一个子节点。 | ||
|
|
||
| <img src="F:\zxh\研二下\kaiyuan\dfs\dfs_intro.gif" align = left style="zoom:50%;" /> |
|
|
||
| ## 深度优先搜索的应用 | ||
|
|
||
| 1. 树的遍历或搜索(前序遍历,深度,路径和等等) |
There was a problem hiding this comment.
不仅仅局限于「前序遍历」。「中序遍历」和「后序遍历」都是「树」问题上的「深度优先搜索」的细分。
| ## 深度优先搜索的应用 | ||
|
|
||
| 1. 树的遍历或搜索(前序遍历,深度,路径和等等) | ||
| 2. 图的遍历或搜索(Dijkstra 算法,Floyd算法) |
There was a problem hiding this comment.
Dijkstra 算法,Floyd 算法(Floyd 后面空一格)的思想更像广度优先搜索,放在这里提或许没有必要(意见仅供参考)。
|
|
||
| ## 深度优先搜索的学习建议 | ||
|
|
||
| 其实 DFS 算法并非只适用于狭义的二叉树这种数据结构,而是一种算法思想。与其说 DFS 算法的应用主要在树与图的遍历或搜索,不如说可以将实际问题所使用的数据结构抽象为树或图。 |
There was a problem hiding this comment.
这里提得特别好,需要读者有一定建模的能力,能够把一个实际场景下的问题转换成树形问题或者图形问题。
| 这里根据本人对该算法的一点了解给初学者几点建议: | ||
|
|
||
| 1. 程序员需要拥有**实际问题的转化能力**。顾名思义,需要能够将实际问题抽象成算法问题,进而使用对应算法来解决问题。我们需要知道这种问题需要用 DFS 算法来解决,这种能力需要一定题量的积累和理解。 | ||
| 2. 在 DFS 算法的使用过程中,我们需要注意深度优先搜索是一个非常耗时的过程,需要对算法进行必要的剪枝,诸如记忆化数组。 |
There was a problem hiding this comment.
「记忆化数组」这个概念可能是作者自创的,想一想有没有专业的说法。在图问题里必须使用「记忆化」,它不是一个优化的措施。
剪枝通常需要对问题有足够深的了解,通常需要借助一定经验和技巧。
|
|
||
| 1. 程序员需要拥有**实际问题的转化能力**。顾名思义,需要能够将实际问题抽象成算法问题,进而使用对应算法来解决问题。我们需要知道这种问题需要用 DFS 算法来解决,这种能力需要一定题量的积累和理解。 | ||
| 2. 在 DFS 算法的使用过程中,我们需要注意深度优先搜索是一个非常耗时的过程,需要对算法进行必要的剪枝,诸如记忆化数组。 | ||
| 3. 当算法出现问题时,建议**手画递归树**和**关键位置打印参数**,避免单纯的看代码 debug。 |
There was a problem hiding this comment.
这里「打印参数」提得特别好。
补充一下「手动画递归树」其实在很多时候,是在解决问题之前的操作。
| 2. 在 DFS 算法的使用过程中,我们需要注意深度优先搜索是一个非常耗时的过程,需要对算法进行必要的剪枝,诸如记忆化数组。 | ||
| 3. 当算法出现问题时,建议**手画递归树**和**关键位置打印参数**,避免单纯的看代码 debug。 | ||
|
|
||
| 最后,深度优先搜索的应用广泛,也是动态规划入门必备的算法思想,希望胖友们好好学习! |
There was a problem hiding this comment.
这里提供一些观点供作者参考:
- 深度优先遍历「由于一条路走到底」的特点,符合后进先出的特点,因此需要借助栈;
- 而递归函数就可以使用到编程语言的方法栈,因此深度优先遍历通常需要通过编写递归函数实现;
- 对递归函数的理解是「动态规划」的基础。
「胖友们」这个提法可能对部分读者不是很友好,参考替换词汇:「盆友」、「旁友」(上海话)、「未来的算法大牛」等。
写了DFS的第一章。