在JS中需要递归的帮助

时间:2013-05-08 15:48:12

标签: recursion

我在递归时遇到了很多麻烦。我可以做简单的递归,但这对我来说并不容易。我的目标是加快这种搜索算法。我猜测递归会有所帮助。在具有子项的简单43节点树上花费15秒。下面是我的展开的递归fomr代码的工作原理。

var nodeList = new Array();
         var removeList = new Array();
         var count = 0;
         var foundInThisNodeTree;

         var find = function ( condition )
         {
         }

         while ( this.treeIDMap.igTree( "nodeByPath", count ).data() )
         {
             var foundInThisNodeTree = false;
             var n;
             n = this.treeIDMap.igTree( "nodeFromElement", this.treeIDMap.igTree( "nodeByPath", count ) )
             if ( n.data.ITEM.indexOf( filter ) > -1 ) { foundInThisNodeTree = true; }
             else {//look deeper
                 var i = 0;
                 while ( this.treeIDMap.igTree( "nodeByPath", count + "_" + i ).data() )
                 {
                     n = this.treeIDMap.igTree( "nodeFromElement", this.treeIDMap.igTree( "nodeByPath", count + "_" + i ) );
                     if ( n.data.ITEM.indexOf( filter ) > -1 ) { foundInThisNodeTree = true; break; }
                     else {//look deeper
                         var j = 0;
                         while ( this.treeIDMap.igTree( "nodeByPath", count + "_" + i + "_" + j ).data() )
                         {
                             n = this.treeIDMap.igTree( "nodeFromElement", this.treeIDMap.igTree( "nodeByPath", count + "_" + i + "_" + j ) );
                             if ( n.data.ITEM.indexOf( filter ) > -1 ) { foundInThisNodeTree = true; break; }
                             else {//look deeper
                                 var k = 0;
                                 while ( this.treeIDMap.igTree( "nodeByPath", count + "_" + i + "_" + j + "_" + k ).data() )
                                 {
                                     n = this.treeIDMap.igTree( "nodeFromElement", this.treeIDMap.igTree( "nodeByPath", count + "_" + i + "_" + j + "_" + k ) );
                                     if ( n.data.ITEM.indexOf( filter ) > -1 ) { foundInThisNodeTree = true; break; }
                                     k++;
                                 }
                             }

                             j++;
                         }
                     }
                     i++;
                 }
             }
             if ( !foundInThisNodeTree ) this.treeIDMap.igTree("removeAt", ""+count )
             else count++;
         }
** * Mirco Ellmann建议的第二次修订 * ****

var nodeList = new Array();
         var removeList = new Array();
         var count = 0;
         var foundInThisNodeTree;
         filter = filter.toLowerCase();
         while ( this.treeIDMap.igTree( "nodeByPath", count ).data() )
         {
             var foundInThisNodeTree = false;
             var n;
             n = this.treeIDMap.igTree( "nodeFromElement", this.treeIDMap.igTree( "nodeByPath", count ) )
             if ( n.data.ITEM.toLowerCase().indexOf( filter ) > -1 ) { foundInThisNodeTree = true; }
             else {//look deeper
                 var i = 0;
                 n = this.treeIDMap.igTree( "childrenByPath", count );
                 while ( n[i] )
                 {
                     if ( n[i].data.ITEM.indexOf( filter ) > -1 ) { foundInThisNodeTree = true; break; }
                         var j = 0;
                         n = this.treeIDMap.igTree( "childrenByPath", count + "_" + i );
                         while ( n[j]  )
                         {
                             if ( n[j].data.ITEM.indexOf( filter ) > -1 ) { foundInThisNodeTree = true; break; }
                                 var k = 0;
                                 n = this.treeIDMap.igTree( "childrenByPath", count + "_" + i + "_" + j);
                                 while ( n[k] )
                                 {
                                     if ( n[k].data.ITEM.indexOf( filter ) > -1 ) { foundInThisNodeTree = true; break; }
                                     k++;
                                 }
                             j++;
                         }

                     i++;
                 }
             }
             if ( !foundInThisNodeTree ) this.treeIDMap.igTree("removeAt", ""+count )
             else count++;
         }

**** 使用我的分支树来获取数据,无需对树进行任何调用 * ***

 var count = 0;
 var foundInThisNodeTree;
 filter = filter.toLowerCase();
 while ( this.treeIDMap.igTree( "nodeByPath", count ).data() )
 {
     var foundInThisNodeTree = false;
     var n;
     n = this.treeIDMap.igTree( "nodeFromElement", this.treeIDMap.igTree( "nodeByPath", count ) )
     if ( n.data.ITEM.toLowerCase().indexOf( filter ) > -1 ) { foundInThisNodeTree = true; }
     if ( n.data.branch )//look at all childer under the root node
     {      
         var i = 0;
         n = n.data.branch;
         while ( n[i] )//look at all childer under the root node
         {      
            if ( n[i].ITEM.toLowerCase().indexOf( filter ) > -1 ) { foundInThisNodeTree = true; break; }
            while ( n[i].branch )//look deeper
            {
                var j = 0;
                n = n[i].branch;
                if ( n[j].ITEM.toLowerCase().indexOf( filter ) > -1 ) { foundInThisNodeTree = true; break; }
                while ( n[j].branch )//look deeper
                {
                    var k = 0;
                    n = n[j].branch;
                    if ( n[k].ITEM.toLowerCase().indexOf( filter ) > -1 ) { foundInThisNodeTree = true; break; }
                    k++;
                }

                j++;
            }

             i++;
         }
     }
     if ( !foundInThisNodeTree ) this.treeIDMap.igTree("removeAt", ""+count )
     else count++;
 }

3 个答案:

答案 0 :(得分:0)

而不是总是使用" nodeByPath"你应该使用" childrenByPath"。

可以最大限度地减少对igTree的搜索调用。

PS:使用不替换;)

答案 1 :(得分:0)

你并不是真的以递归的方式做这件事。您正在为层次结构中的每个级别重复代码。你想要的是一个辅助函数,它将当前的node-path作为参数,并递归地为每个子节点调用相同的方法,并将其id添加到当前节点的路径中。递归意味着代码应该适用于任何深度的树。对我而言,您的代码看起来只适用于设定的深度。

对于速度问题,可能存在两个问题。我没有真正仔细阅读你的代码,所以我留给你找出哪一个更有可能。

  1. 您可能正在重新访问节点。如果是这样,显然会影响性能。

  2. 您正在使用的框架在查找节点时可能会很慢。一种解决方案可能是找到替代方法来调用框架,这是为了你正在做的事情。例如,框架可能在内部具有层次结构表示,但必须重建它或在传递完整路径时解析它。寻找采用源和相对路径的方法。如果这不是问题,那么框架可能会很慢,您可能更好地阅读所有节点并构建自己的内存树以供使用。

答案 2 :(得分:0)

好的,我找到了一种使用数据提供程序并使用普通Json搜索的方法。如果有人能加快速度,我也要心存感激。我只是从15秒到1秒。这个有我需要的递归。

   findInObject = function( obj, prop, val )
 {
     if ( obj !== null && obj.hasOwnProperty( prop ) && obj[prop].toLowerCase().indexOf(val) > -1 )
     {
         return obj;
     } else
     {
         for ( var s in obj )
         {
             if ( obj.hasOwnProperty( s ) && typeof obj[s] == 'object' && obj[s] !== null )
             {
                 var result = findInObject( obj[s], prop, val );
                 if ( result !== null )
                 {
                     return result;
                 }
             }
         }
     }
     return null;
 }

 for ( var i = 0; i < this.treeData.length; i++)
 {
     if ( findInObject( this.treeData[i], "ITEM", filter ) ) foundNodes.push( this.treeData[i] )//does the node have a match?
 }

 this.treeIDMap.igTree( { dataSource: foundNodes } );
 this.treeIDMap.igTree( "dataBind" );

};