问题描述
|
虽然递归扫描通常用于扫描嵌套的对象/数据。如果某些对象相互引用,它可能会无限循环。那么,在不使计算机崩溃或不跳过指定参数的情况下扫描所有项目的最有效方法是什么?
这是递归扫描器的示例...
/**
* Triggers the scan function for each object given
**/
function recursiveScanner( object:*,scanFunction:Function ):void {
if( typeof(object) == \'object\' ) {
for( var key:String in object ) {
recursiveScanner( object[key],scanFunction );
}
} else {
scanFunction.call(this,object);
}
}
但是,当传入以下内容时,会发生巨大的问题
//...
obj1.next = obj2;
//...
obj2.next = obj3;
//...
obj3.next = obj1;
//...
recursiveScanner(obj1,scanFuction);
这些对象将触发一个永恒循环的扫描。那么有没有办法解决这个问题?
我确实相信C / C ++:每个scanFunction调用都会添加到由扫描的“内存地址”组成的列表中,从而防止重复。在AS3中甚至有可能吗?有没有更优雅的方式?
解决方法
使用ѭ2来保留已扫描对象的列表,如果之前已扫描过它们,则将其忽略:
/**
* Triggers the scan function for each object given
**/
function recursiveScanner( object:*,scanFunction:Function,ignoreList:Dictonary = null ):void {
// if we have no list,create one
if (!ignoreList) ignoreList = new Dictionary();
// if the item is in the list,we bail
if (ignoreList[object]) return;
// mark the item as scanned before recursing into it
ignoreList[object] = true;
if( typeof(object) == \'object\' ) {
for( var key:String in object ) {
recursiveScanner( object[key],scanFunction,ignoreList );
}
} else {
scanFunction.call(this,object);
}
}
, 好的,接受@grapefrukt的回答,但这是一些背景。
用计算机科学的术语来说,问题等同于遍历可以包含循环的有向图。
基本上有两种幼稚的方式(即不遵循启发式)进行遍历,即深度优先或宽度优先。
我将把它作为练习来确定示例代码是BFS还是DFS。