我有以下递归函数:
function explore(v, componentN) {
return function () {
nodes[v].visited = true;
nodes[v].componentNumber = componentN;
preVisit(v);
adjList[v].forEach((item) => {
if (!nodes[item].visited){
ex(item, componentN)
}
});
postVisit(v);
return nodes;
}
}
function ex(item, com){
trampoline(function () {
return explore(item, com)
})
}
function trampoline(fn) {
while(fn && typeof fn === 'function') {
fn = fn()
}
}
我想使用setImmediate()
以避免堆栈溢出问题(它应该以这种方式实现,而不是在迭代方法中)。但是,当我执行这个函数时,我res
只得到第一个元素的数组,而如果我不使用它,我会得到所有元素,setImmediate()
并且在我使用时会出现同样的情况nextTick()
(我事先知道应该有多少元素)。我在做什么错,如何在此处正确实现此功能(或模拟)?
这是explore()
应用蹦床之前的功能
function explore(v, componentN) {
nodes[v].visited = true;
nodes[v].componentNumber = componentN;
preVisit(v);
adjList[v].forEach((item) => {
if (!nodes[item].visited){
explore(item, componentN)
}
});
postVisit(v);
return nodes;
}
它接受两个参数:v
是nodes
数组中的索引,应该探索哪个元素,而componentN
它只是图中组件的计数器。explore()
不返回任何内容,它只是nodes
将键下数组中对象的状态v
从未探索更改为已探索。主要问题是这两个函数preVisit(v)
还postVisit(v)
改变了该对象的状态 - 分别写入第一次和第二次访问它的顺序(从先前的调用弹出堆栈时)。当我explore()
用蹦床转换时,他们开始写出意想不到的错误结果。
以这种方式在另一个函数中调用该函数:
for (let i = 0; i < vNum; i++) {
if (nodes[i].visited) continue;
explore(i, cN);
cN++;
}
还有两个功能postVisit
和preVisit
function preVisit(v){
nodes[v].preVisit = visitCounter;
visitCounter++;
}
function postVisit(v) {
nodes[v].postVisit = visitCounter;
visitCounter++;
}