深度优先搜索实现-了解快速代码

时间:2018-12-24 22:15:17

标签: swift data-structures

我正在浏览Tree DS的一些教程,发现这段代码确实让人难以理解。请解释

public func forEachDepthFirst(visit: (TreeNode) -> Void) {
        visit(self) // 1

        children.forEach { // 2
            $0.forEachDepthFirst(visit: visit)
        }
    }
}

我们为什么要在这里访问(自己)?

我在这里https://forums.raywenderlich.com/t/help-understanding-the-recursion-for-depth-first-traversal/56552/2看到了解释,但仍不清楚

2 个答案:

答案 0 :(得分:1)

任何回溯方法都有

1-基本情况:结束运行,在这里是

children.forEach // when children property is empty meaning a leaf node

2例案例

$0.forEachDepthFirst(visit: visit) // call the same method with it's children 

您的方法需要一个闭包/完成操作,对于主根节点内的每个节点都会调用该操作

所以假设您有根

0 
  - 1
     -  1.1 , 1.2 , 1.3

  -  2
     - 2.1 , 2.2 , 2.3

在调用您的函数时会调用0节点

  • 访问(0)

  • children.forEach {// = 1,2

代表0> 1

  • 访问(1)

  • children.forEach {// = 1.1,1.2,1.3

代表0> 2

  • 访问(2)

  • children.forEach {// = 2.1,2.2,2.3


大写字母

对于0> 1> 1.1

  • 访问(1.1)

  • children.forEach {//此处结束,因为没有子级(叶节点)

依次进行1.2,1,3


对于0> 2> 2.1 / 2.2 / 2.3与上述情况相同


如何拨打电话

您的方法是树内的实例方法,因此每个节点都可以调用它,如果您要遍历0的节点,请执行此操作

zeroNode.forEachDepthFirst {  (item) in
  print(item.name) // suppose node object has a name 
}

那么你会得到

0 , 1 , 1.1 , 1.2 , 1.3 , 2.1 , 2.2 , 2.3

就像您为主节点调用visit(NodeObject)并递归所有子节点

答案 1 :(得分:0)

  

为什么我们这里有visit(self)

因为如果不这样做,我们实际上就不会对树上的任何节点

考虑这棵树:

n1 -> n2 -> n3 -> n4

我们现在在forEachDepthFirst上调用方法n1。如果没有visit(self),我们将立即在forEachDepthFirst上调用n2,这会在n3上调用,而会在n4上调用。然后我们停下来。但是我们绝不会调用visit,因此我们会遍历树中的每个节点而无需对这些节点做任何事。