使用Javascript进行深度优先遍历

使用Javascript进行深度优先遍历,javascript,tree,Javascript,Tree,我一直在读以下文章: 这将设置以下类和方法 function Node(data) { this.data = data; this.parent = null; this.children = []; } function Tree(data) { var node = new Node(data); this._root = node; } Tree.prototype.traverseDF = function(callback) {

我一直在读以下文章:

这将设置以下类和方法

function Node(data) {
    this.data = data;
    this.parent = null;
    this.children = [];
}

function Tree(data) {
    var node = new Node(data);
    this._root = node;
}

Tree.prototype.traverseDF = function(callback) {
    (function recurse(currentNode) {
        for (var i = 0, length = currentNode.children.length; i < length; i++) {
            recurse(currentNode.children[i]);
        }

        callback(currentNode);
    })(this._root);

};
var tree = new Tree('one');

tree._root.children.push(new Node('two'));
tree._root.children[0].parent = tree;

tree._root.children.push(new Node('three'));
tree._root.children[1].parent = tree;

tree._root.children.push(new Node('four'));
tree._root.children[2].parent = tree;

tree._root.children[0].children.push(new Node('five'));
tree._root.children[0].children[0].parent = tree._root.children[0];

tree._root.children[0].children.push(new Node('six'));
tree._root.children[0].children[1].parent = tree._root.children[0];

tree._root.children[2].children.push(new Node('seven'));
tree._root.children[2].children[0].parent = tree._root.children[2];
所以当我们最终进行遍历调用时

tree.traverseDF(function(node) {
    console.log(node.data)
});
它返回:

five
six
two
three
seven
four
one
这打破了我对“深度优先”的理解。如果您先搜索深度,wikipedia将显示以下图像:

在这张图片下,感觉前面的代码应该打印:

one
two
five 
six
根据维基百科:

一个从根开始(在图形中选择任意节点作为根),在回溯之前尽可能沿着每个分支进行探索


这个问题中当前的实现实际上是从最底层开始打印最小的孩子,并向上移动,而不是从上到下维基百科如何定义它。有人能帮我理解我遗漏了什么吗?

您的代码确实执行深度优先搜索,但在决定节点何时被视为“访问”时仍然有灵活性:是在第一次相遇时,还是在回溯时

如果在循环之前移动
console.log
,您将得到预期的结果:

Tree.prototype.traverseDF = function(callback) {
    (function recurse(currentNode) {
        callback(currentNode); // <-----
        for (var i = 0, length = currentNode.children.length; i < length; i++) {
            recurse(currentNode.children[i]);
        }
    })(this._root);
};
Tree.prototype.traverseDF=函数(回调){
(函数递归(currentNode){

回调(currentNode);//我可以问一下这是如何自终止的吗?是因为当不再有子循环时,for循环被绕过,回调被调用吗?我忘了问这个问题。这是自终止的,因为树的叶子上没有递归调用,没有子循环,因此循环对for没有任何迭代在这种情况下,唯一发生的事情就是回调函数的调用,递归返回到上一次调用。在那里,循环将进入下一次迭代,…等等。
Tree.prototype.traverseDF = function(callback) {
    (function recurse(currentNode) {
        callback(currentNode); // <-----
        for (var i = 0, length = currentNode.children.length; i < length; i++) {
            recurse(currentNode.children[i]);
        }
    })(this._root);
};