使用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);
};