Javascript 无法理解此回调函数的作用(BFS,树的宽度级别)
我目前正在研究和学习树,并一直在处理不同的遍历实现Javascript 无法理解此回调函数的作用(BFS,树的宽度级别),javascript,algorithm,callback,tree,breadth-first-search,Javascript,Algorithm,Callback,Tree,Breadth First Search,我目前正在研究和学习树,并一直在处理不同的遍历实现 class Node { constructor(data) { this.data = data; this.children = []; } add(data) { this.children.push(new Node(data)); } remove(data) { this.children = this.children.filter(node => {
class Node {
constructor(data) {
this.data = data;
this.children = [];
}
add(data) {
this.children.push(new Node(data));
}
remove(data) {
this.children = this.children.filter(node => {
return node.data !== data;
})
}
}
traverseBF(fn) {
const arr = [this.root];
while (arr.length) {
const node = arr.shift();
arr.push(...node.children);
fn(node); //what role does this play?
}
return count;
}
traverseDF(fn) {
const arr = [this.root];
while (arr.length) {
const node = arr.shift();
arr.unshift(...node.children);
fn(node); //what role does this play???
}
}
我想我已经理解了回调具有声明它的上下文,并且能够访问外部函数中的变量,我认为是arr保持最新的原因,回调函数对于BFS/DFS在这个实例中的工作是不可或缺的。然而,学习计算宽度水平打破了我的理解
function levelWidth(root) {
const arr = [root, 's'];
const counters = [0];
while (arr.length > 1) {
const node = arr.shift();
if (node === 's') {
counters.push(0);
arr.push('s');
} else {
arr.push(...node.children);
counters[counters.length - 1]++;
}
}
return counters;
}
这里还没有回调,这个BFS搜索和遍历工作正常。有谁能帮我更好地理解为什么一开始就需要它,而不是这次
当我这样调用遍历时,到底发生了什么
const letters = [];
const t = new Tree();
t.root = new Node('a');
t.root.add('b');
t.root.add('d');
t.root.children[0].add('c');
t.root.children[1].add('e');
t.traverseBF(node => {
letters.push(node.data);
});
console.log(letters);
这里没有对错 回调版本有两种不同:
- 它不使用访问的节点应用任何逻辑。它只负责遍历,不负责任何其他逻辑。任何特定的逻辑都留给调用方,调用方可以为此目的传递回调。在最后一个示例中,该特定逻辑包括将节点的
值收集到一个数组中。但是请注意,遍历函数不知道这个逻辑,这是一个很好的关注分离 注意:数据
末尾的transversebf(fn)
不应该存在(没有返回计数
)计数
- 它不会让调用方一直等待,直到访问了所有节点
*
)
这里的另一个优点是调用方总是可以决定停止遍历。在上面的代码中,循环的早期中断实际上意味着遍历将不再完成。对于前面提到的所有其他方法,您必须触发一个异常以使其成为可能;在所有其他情况下,遍历必须运行到完成。谢谢,这非常有帮助。
* traverseBF() {
const arr = [this.root];
while (arr.length) {
const node = arr.shift();
arr.push(...node.children);
yield node; // <---
}
}
* traverseDF() {
const arr = [this.root];
while (arr.length) {
const node = arr.shift();
arr.unshift(...node.children);
yield node; // <---
}
}
let letters = [];
for (let node of t.traverseDF()) {
// do something with this node before continuing the traversal
letters.push(node.data);
}
console.log(letters);