我有以下递归函数:
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++;
}