有向循环图遍历算法 (JavaScript)
我有一个连通的有向循环图。任务是发现图中的每个节点,而不会像常规树遍历算法那样陷入无限循环。
您可以假设我已经知道从哪个节点开始以到达有向图中的所有点,并且对于每个节点,我都有一个函数将返回它指向的节点。是否有已知的算法来查找所有节点?
主要问题实际上是避免循环,如果有一种方法可以做到这一点,而无需跟踪每个节点并将其与已遍历的节点列表进行比较,我会很高兴。
如果您需要更多详细信息,实际任务是获取 JavaScript 中每个命名函数的列表,包括作为其他对象的属性的函数。所以我尝试了类似下面的方法,因为我认为 JS 对象彼此的引用形成了一棵树(但当然事实并非如此):
function __findFunctions(obj){
for (var f in obj){
// for special case of edge with self
if (obj === obj[f]){
continue
}
if (typeof obj[f] === 'function' &&
obj.hasOwnProperty(f) &&
// exclude native functions, we only want user-defined ones
!(/\[(native\scode|object\sfunction)\]/i).test(obj[f].toString()) &&
// exclude functions with __ prefix
!(/^\s*function\s*__/).test(obj[f].toString())
){
document.write(f + "<br/>" + obj[f].toString() + "<hr/>");
}
//alert(typeof obj[f] + "\n" + obj + "\n" + obj[f] + "\n" + f)
__findFunctions(obj[f]);
}
}
__findFunctions(window);
这段代码的问题在于它陷入了循环。
I have a connected, directed, cyclic graph. The task is to discover every single node in the graph without falling into an infinite loop, as a regular tree traversal algorithm will do.
You can assume that I already know what node to start at so as to reach all points in the directed graph, and that for each node I have a function that will return the nodes it directs to. Is there a known algorithm for finding all nodes?
The main issue is really avoiding cycles, and I would love it if there was a way to do that without keeping track of every single node and comparing it with a list of nodes that has already been traversed.
If you need more details, the actual task is to get a list of every named function in JavaScript, including functions that are properties of other objects. So I tried something like the following, as I thought the JS objects' references to each other made a tree (but of course it doesn't):
function __findFunctions(obj){
for (var f in obj){
// for special case of edge with self
if (obj === obj[f]){
continue
}
if (typeof obj[f] === 'function' &&
obj.hasOwnProperty(f) &&
// exclude native functions, we only want user-defined ones
!(/\[(native\scode|object\sfunction)\]/i).test(obj[f].toString()) &&
// exclude functions with __ prefix
!(/^\s*function\s*__/).test(obj[f].toString())
){
document.write(f + "<br/>" + obj[f].toString() + "<hr/>");
}
//alert(typeof obj[f] + "\n" + obj + "\n" + obj[f] + "\n" + f)
__findFunctions(obj[f]);
}
}
__findFunctions(window);
The problem with this code is that it gets stuck in cycles.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
它可能不像检查已遍历节点的列表那么糟糕。相反,您可以为每个节点提供某种唯一的 ID:
等等。
然后您可以在遍历时将每个节点的 ID 添加到哈希中:
稍后,当您需要检查它是否已经被遍历时:
或者,对于一个真正基本的解决方案,只需在您遍历的每个对象上设置一些属性:
It may not be as bad as checking a list of already-traversed nodes. You could, instead, give each node a unique ID of some sort:
etc.
Then you can add each node's ID to a hash while you traverse:
And later on, when you need to check whether or not its already been traversed:
Or, for a really rudimentary solution, simply set some property on each object that you traverse:
如果您想避免循环,您需要维护已访问节点的列表。
例如
You would need to maintain a list of already visited nodes if you want to avoid cycles.
E.g.
这是一个快速答案,您可以在 codePen 上查看
https://codepen.io/vjuju/pen/PoXZJQo
Here is a quick answer that you can check on codePen
https://codepen.io/vjuju/pen/PoXZJQo