js中如何将递归方法改成非递归方法
how to change recursive method into non recursive one in js
我写了一个小代码来从 GitHub 加载追随者树。
它适用于我的递归版本,但我无法获得我的 "stack-que" 版本 运行。
我在完成循环后收到了我的回复,这就是问题所在;我的递归解决方案使用相同的 loadFollowers 方法,但由于其调用结构,它会生成所需的树。
我是否应该以某种方式关闭通话中的异步功能?
function loadFollowers(user,field,callback){
path = 'https://api.github.com/users/'+user.info[field]+'/followers';
path += '?client_id=' + pass.client_id + '&client_secret='+pass.client_secret
console.log("path:"+path+' field: '+field+' node: '+user);
$.get(path,function(followers){
for(var i = 0;i < followers.length; i++){
current = new Node();
current.info = followers[i];
user.addFollower(current);
callback();
};
});
}
function loadNetworkNonROld(node,depth,field){
var toVisit = [];
var visited =[];
var deep;
var current;
var curr;
toVisit.push([node,depth]); // saves [node,level] to control how deep it is
// starts at initial node
while (toVisit.length > 0){
curr = toVisit.shift();
current = curr[0];
deep = curr[1];
if((visited.indexOf(current.info[field])===-1) && (deep > 0)){
visited.push(current.info[field]);
loadFollowers(current,field,function(){
for(var i=0;i < current.followers.length; i++){
toVisit.push([current.followers[i],deep-1]);
}
});
}
}
return visited;
}
工作正常的递归版本如下:
function loadNetwork(node,depth,field){
loadFollowers(node,field,function(){
if (depth == 0){return;}
for(var i=0; i < node.followers.length; i++){
current = node.followers[i];
id = current.info[field];
if (networkAllUsers.indexOf(id)===-1)
{
networkAllUsers.push(id);
console.log(id);
loadNetwork(current,depth-1,field);
}
}});
}
github link 是:https://github.com/marcinwal/myownnode.git
代码在 public/javascript/main.js 文件中。
看起来问题很可能是迭代版本中 loadFollowers 的异步 运行ning。
然而,你的问题的关键问题在于,当你向我们展示代码时,你没有向我们展示你遇到的错误,也没有说明 'stack-que' 是什么或回复评论要求澄清。
此外,您没有向我们提供有关如何 运行 您的代码来复制您遇到的问题的说明。查看您的代码,我进行了一系列猜测,您可以在这个屏幕截图中看到一些结果:
并且我适当地缩进了您的迭代代码,并添加了一些日志记录以生成上述输出的一部分:
function loadNetworkNonROld(node,depth,field){
var toVisit = [];
var visited =[];
var deep;
var current;
var curr;
toVisit.push([node,depth]); // saves [node,level] to control how deep it is
// starts at initial node
while (toVisit.length > 0){
console.log(toVisit)
curr = toVisit.shift();
current = curr[0];
deep = curr[1];
if((visited.indexOf(current.info[field])===-1) && (deep > 0)){
visited.push(current.info[field]);
console.log(visited)
loadFollowers(current,field,function(){
for(var i=0;i < current.followers.length; i++){
toVisit.push([current.followers[i],deep-1]);
console.log('loadFollowers:' + toVisit)
}
});
}
}
return visited;
}
现在我可以花更多的精力来研究你的代码,猜测我们是否得到了一些输出,你有什么,但你并没有让人们很容易提供帮助。
从我在控制台日志中看到的情况来看,在我看来,您正在将所有节点推到深度 1,而它们永远不会达到深度 0,因此它只是 运行 永远持续不断。而在递归版本中,深度变为 0。
我修改了你的代码:
while (toVisit.length > 0){
console.log(toVisit)
curr = toVisit.shift();
current = curr[0];
deep = curr[1];
if((visited.indexOf(current.info[field])===-1) && (deep > 0)){
visited.push(current.info[field]);
console.log('loadNetworkNonROld: '+deep);
loadFollowers(current,field,deep,function(depth){
console.log('loadFollowers:' + (depth-1));
for(var i=0;i < current.followers.length; i++){
toVisit.push([current.followers[i],(depth-1)]);
}
});
}
}
console.log('loadNetworkNonROld: visited:'+JSON.stringify(visited));
return visited;
}
对 loadFollowers 函数进行并行更改,以便实际传递深度值。现在代码 运行s 没有永远迭代,但是 javascript 的异步性质意味着结果在任何网络调用完成之前返回 - 因此访问的结果只是第一个用户。
我写了一个小代码来从 GitHub 加载追随者树。
它适用于我的递归版本,但我无法获得我的 "stack-que" 版本 运行。
我在完成循环后收到了我的回复,这就是问题所在;我的递归解决方案使用相同的 loadFollowers 方法,但由于其调用结构,它会生成所需的树。
我是否应该以某种方式关闭通话中的异步功能?
function loadFollowers(user,field,callback){
path = 'https://api.github.com/users/'+user.info[field]+'/followers';
path += '?client_id=' + pass.client_id + '&client_secret='+pass.client_secret
console.log("path:"+path+' field: '+field+' node: '+user);
$.get(path,function(followers){
for(var i = 0;i < followers.length; i++){
current = new Node();
current.info = followers[i];
user.addFollower(current);
callback();
};
});
}
function loadNetworkNonROld(node,depth,field){
var toVisit = [];
var visited =[];
var deep;
var current;
var curr;
toVisit.push([node,depth]); // saves [node,level] to control how deep it is
// starts at initial node
while (toVisit.length > 0){
curr = toVisit.shift();
current = curr[0];
deep = curr[1];
if((visited.indexOf(current.info[field])===-1) && (deep > 0)){
visited.push(current.info[field]);
loadFollowers(current,field,function(){
for(var i=0;i < current.followers.length; i++){
toVisit.push([current.followers[i],deep-1]);
}
});
}
}
return visited;
}
工作正常的递归版本如下:
function loadNetwork(node,depth,field){
loadFollowers(node,field,function(){
if (depth == 0){return;}
for(var i=0; i < node.followers.length; i++){
current = node.followers[i];
id = current.info[field];
if (networkAllUsers.indexOf(id)===-1)
{
networkAllUsers.push(id);
console.log(id);
loadNetwork(current,depth-1,field);
}
}});
}
github link 是:https://github.com/marcinwal/myownnode.git 代码在 public/javascript/main.js 文件中。
看起来问题很可能是迭代版本中 loadFollowers 的异步 运行ning。
然而,你的问题的关键问题在于,当你向我们展示代码时,你没有向我们展示你遇到的错误,也没有说明 'stack-que' 是什么或回复评论要求澄清。
此外,您没有向我们提供有关如何 运行 您的代码来复制您遇到的问题的说明。查看您的代码,我进行了一系列猜测,您可以在这个屏幕截图中看到一些结果:
并且我适当地缩进了您的迭代代码,并添加了一些日志记录以生成上述输出的一部分:
function loadNetworkNonROld(node,depth,field){
var toVisit = [];
var visited =[];
var deep;
var current;
var curr;
toVisit.push([node,depth]); // saves [node,level] to control how deep it is
// starts at initial node
while (toVisit.length > 0){
console.log(toVisit)
curr = toVisit.shift();
current = curr[0];
deep = curr[1];
if((visited.indexOf(current.info[field])===-1) && (deep > 0)){
visited.push(current.info[field]);
console.log(visited)
loadFollowers(current,field,function(){
for(var i=0;i < current.followers.length; i++){
toVisit.push([current.followers[i],deep-1]);
console.log('loadFollowers:' + toVisit)
}
});
}
}
return visited;
}
现在我可以花更多的精力来研究你的代码,猜测我们是否得到了一些输出,你有什么,但你并没有让人们很容易提供帮助。
从我在控制台日志中看到的情况来看,在我看来,您正在将所有节点推到深度 1,而它们永远不会达到深度 0,因此它只是 运行 永远持续不断。而在递归版本中,深度变为 0。
我修改了你的代码:
while (toVisit.length > 0){
console.log(toVisit)
curr = toVisit.shift();
current = curr[0];
deep = curr[1];
if((visited.indexOf(current.info[field])===-1) && (deep > 0)){
visited.push(current.info[field]);
console.log('loadNetworkNonROld: '+deep);
loadFollowers(current,field,deep,function(depth){
console.log('loadFollowers:' + (depth-1));
for(var i=0;i < current.followers.length; i++){
toVisit.push([current.followers[i],(depth-1)]);
}
});
}
}
console.log('loadNetworkNonROld: visited:'+JSON.stringify(visited));
return visited;
}
对 loadFollowers 函数进行并行更改,以便实际传递深度值。现在代码 运行s 没有永远迭代,但是 javascript 的异步性质意味着结果在任何网络调用完成之前返回 - 因此访问的结果只是第一个用户。