Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dfs snow #23

Open
wants to merge 3 commits into
base: docsify
Choose a base branch
from
Open

Dfs snow #23

wants to merge 3 commits into from

Conversation

Squirtle12
Copy link

写了DFS的第一章。

@liweiwei1419 liweiwei1419 self-requested a review May 17, 2020 10:22
Copy link
Contributor

@liweiwei1419 liweiwei1419 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

整体没有大问题,深度优先搜索在开始章节能期待够给读者在脑海里建立「深搜」的思想。

看看能不能制作更生动的图形,或者在网上找一下。达到的效果是,读者一想到深搜,就想到你说的「一条道走到底」,我就得就很成功了。

@@ -0,0 +1,27 @@
# 深度优先搜索算法

**深度优先搜索**(Depth-First-Search, DFS)是一种用于遍历或搜索树或图的算法,与深度优先搜索密切相关的是**广度优先算法**与**回溯算法**。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

「回溯算法」本质上行还是一种「深度优先搜索」的算法,这个算法强调了使用一份状态变量去搜索整个状态空间。与「广度优先搜索」还是不太一样的,可以单独提一句,不用放在和「广度优先遍历」一块写。

其实,在适当的地方(或者是后面的例题里)。树中因为不存在环,因此在遍历的过程中无需记录哪些节点已经访问过。但是在图中,就不一样,一般而言需要使用 visited 数组或者哈希表记录已经访问过的节点。


**深度优先搜索**(Depth-First-Search, DFS)是一种用于遍历或搜索树或图的算法,与深度优先搜索密切相关的是**广度优先算法**与**回溯算法**。

深度优先遍历会 遵循**一条路走到黑,不撞叶子节点不回头**的原则。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里空格没有必要。

另外这句话其实很突出地说明了「深度优先遍历」的思想,建议放在文章的开头。「叶子节点」有点特殊,前面得先说,在「树形问题」里,「叶子节点」这个概念出现才不会很突兀,「叶子节点」是一条路径的尽头,「深度优先遍历」的思想是直到走到尽头的时候才会回头。


深度优先遍历会 遵循**一条路走到黑,不撞叶子节点不回头**的原则。

下图以二叉树为例讲解 DFS 算法的基本思想。DFS 算法会沿着二叉树的一条路搜索,直至走到叶子节点。当搜索至叶子节点时,会进行**回溯**,回溯到父节点,并继续父节点的另一个子节点。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

「回溯」这个词其实并不是那么口语化,事实上,它有专门的含义(上面的意见也提到了),这里直接写「回头」更直接。


下图以二叉树为例讲解 DFS 算法的基本思想。DFS 算法会沿着二叉树的一条路搜索,直至走到叶子节点。当搜索至叶子节点时,会进行**回溯**,回溯到父节点,并继续父节点的另一个子节点。

<img src="F:\zxh\研二下\kaiyuan\dfs\dfs_intro.gif" align = left style="zoom:50%;" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

图片地址修改成相对路径。


## 深度优先搜索的应用

1. 树的遍历或搜索(前序遍历,深度,路径和等等)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

不仅仅局限于「前序遍历」。「中序遍历」和「后序遍历」都是「树」问题上的「深度优先搜索」的细分。

## 深度优先搜索的应用

1. 树的遍历或搜索(前序遍历,深度,路径和等等)
2. 图的遍历或搜索(Dijkstra 算法,Floyd算法)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dijkstra 算法,Floyd 算法(Floyd 后面空一格)的思想更像广度优先搜索,放在这里提或许没有必要(意见仅供参考)。


## 深度优先搜索的学习建议

其实 DFS 算法并非只适用于狭义的二叉树这种数据结构,而是一种算法思想。与其说 DFS 算法的应用主要在树与图的遍历或搜索,不如说可以将实际问题所使用的数据结构抽象为树或图。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里提得特别好,需要读者有一定建模的能力,能够把一个实际场景下的问题转换成树形问题或者图形问题。

这里根据本人对该算法的一点了解给初学者几点建议:

1. 程序员需要拥有**实际问题的转化能力**。顾名思义,需要能够将实际问题抽象成算法问题,进而使用对应算法来解决问题。我们需要知道这种问题需要用 DFS 算法来解决,这种能力需要一定题量的积累和理解。
2. 在 DFS 算法的使用过程中,我们需要注意深度优先搜索是一个非常耗时的过程,需要对算法进行必要的剪枝,诸如记忆化数组。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

「记忆化数组」这个概念可能是作者自创的,想一想有没有专业的说法。在图问题里必须使用「记忆化」,它不是一个优化的措施。

剪枝通常需要对问题有足够深的了解,通常需要借助一定经验和技巧。


1. 程序员需要拥有**实际问题的转化能力**。顾名思义,需要能够将实际问题抽象成算法问题,进而使用对应算法来解决问题。我们需要知道这种问题需要用 DFS 算法来解决,这种能力需要一定题量的积累和理解。
2. 在 DFS 算法的使用过程中,我们需要注意深度优先搜索是一个非常耗时的过程,需要对算法进行必要的剪枝,诸如记忆化数组。
3. 当算法出现问题时,建议**手画递归树**和**关键位置打印参数**,避免单纯的看代码 debug。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里「打印参数」提得特别好。

补充一下「手动画递归树」其实在很多时候,是在解决问题之前的操作。

2. 在 DFS 算法的使用过程中,我们需要注意深度优先搜索是一个非常耗时的过程,需要对算法进行必要的剪枝,诸如记忆化数组。
3. 当算法出现问题时,建议**手画递归树**和**关键位置打印参数**,避免单纯的看代码 debug。

最后,深度优先搜索的应用广泛,也是动态规划入门必备的算法思想,希望胖友们好好学习!
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里提供一些观点供作者参考:

  • 深度优先遍历「由于一条路走到底」的特点,符合后进先出的特点,因此需要借助栈;
  • 而递归函数就可以使用到编程语言的方法栈,因此深度优先遍历通常需要通过编写递归函数实现;
  • 对递归函数的理解是「动态规划」的基础。

「胖友们」这个提法可能对部分读者不是很友好,参考替换词汇:「盆友」、「旁友」(上海话)、「未来的算法大牛」等。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants