Javascript 与 Python 中的递归深度优先搜索

问题描述

所以我在 AlgoExpert 上做算法题,遇到了一个递归 DFS 算法。最初我尝试用 JavaScript 解决它,但遇到了问题。当我观看代码演练时,我发现它的解决方法非常简单。

这是 Python 解决方案:

def depthFirstSearch(self,array):
    array.append(self.name);
    for child in self.children:
        child.depthFirstSearch(array);
    return array

我的问题是,您将如何在 JavaScript 中实现相同的功能?我试着做:

function depthFirstSearch(array) {
    array.push(this.name);
    for(let i=0; i < array.length; i++) {
        depthFirstSearch(array[i]);
    };
    return array;
}

我不断收到错误消息:

未定义depthFirstSearch

当我尝试在自身内部递归调用函数时,为什么我会在 JavaScript 中收到错误,我很困惑?

这是整个代码片段:

class Node {
    constructor(name) {
        this.name = name;
        this.children = [];
    }

    addChild(name) {
        this.children.push(new Node(name));
        return this;
    }

    depthFirstSearch(array) {
       /*
        * Step 1: Add the root node to the array
        *                   this.name is the root at the start
        * Step 2: Check that the left child node isn't null
        * Step 3: If the left child node isn't null,Add the left child node to the array
        * Step 4: If the left child node is null check the right child node
        * Step 5: If the right child node isn't null,add the right child node to the array
        * Step 6: Repeat steps 1-5 until there are no nodes left to check
        */
        array.push(this.name);
        const children = this.children;
        for(let i=0; i < array.length; i++) {
            depthFirstSearch(array[i]);
        };
        return array;
    }
}

解决方法

几个问题:

  • depthFirstSearchNode 类的方法,不是全局函数,所以应该在节点实例上调用。因此,例如,如果您有一个名为 child 的节点,它应该像 child.depthFirstSearch

  • 由于它是一种方法,因此您不应使用 function 关键字(在 class 构造中)。这已在您问题中的最后一个代码块中正确删除。

  • 传递给 depthFirstSearch 的参数应该是一个数组,但您传递的参数是 array[i],它是一个 节点。它应该只是 array,就像在 Python 代码中一样。

  • 循环不应该在 array 上,而是在当前节点的 children 上,即在 this.children 上。所以你的 i < this.children.length 循环中会有 for

其他一些说明:

  • for 循环后不需要分号。添加它实际上会引入一个(无害的)空语句。
  • 使用 for..of 而不是普通的旧 for 循环可以使代码更短一些,并且更好地模仿 Python 代码的功能。

修正版:

class Node {

    /* ... the other code ... */

    depthFirstSearch(array) {
        array.push(this.name);
        for (let child of this.children) {
            child.depthFirstSearch(array);
        }
        return array;
    }
}