迭代反向前序遍历

时间:2014-10-18 17:39:06

标签: javascript dom recursion tree depth-first-search

我想找到布局直接位于元素上方的项目。在页面的DOM结构中,这意味着某些东西可以嵌套在几层深处,或者它也可能意味着在层次结构中升级几个级别。例如

div.a        
  div.b      
    div.c      
    div.d    
      div.e  
        div.f
    div.g    
  div.h      
  div.i      
div.j        
div.k        

其中.b, .h, .i.a的直接子项,依此类推。

例如,当我致电getBefore($('.h'));时,我希望获取.g。这表面上可能涉及首先命中div.b的预订逆向搜索。

我遇到的问题是,如果不执行全局递归扫描,我很难处理getBefore($('.c'));我希望的情况获取.b因为它是布局中位于它之前的项目。例程,没有全局遍历递归堆栈来更好地了解,会看.b(不知道.d是一个中间孩子并且它不应该递归)并获取最底部的项目在其层次结构中,结果证明是.g,将我们引向错误的方向。

基于这种观察,在我看来,像递归实现一样不能干净利落,因为例程的输入不是根节点,而是某些树的结构未知的一些节点。那么,迭代实现这一点的合理方法是什么呢? DOM给了我指向上移到父节点的指针,我也有指向前一个节点的指针,如果有的话,我还可以获取任何给定模式的子节点列表(如果有的话)。

2 个答案:

答案 0 :(得分:0)

这就是我开始工作的方式。它使用常规递归前序遍历例程的组合,该例程由迭代例程调用,该例程知道要去哪个方向。

迭代例程接受一个节点,并通过调用node = node.previousSibling向上走动兄弟列表。当它到达顶部时,它将转到父:node = node.parentNode。在每一步中,它将调用一个使用标准递归预订搜索的方法,该搜索获取由该节点生根的树中的最后一个合适的项。这种方式.g导致.f,因为$('.g')[0].previousSibling.d.d的最后一项是.f

奇怪的是,向前移动,getAfter()例程执行相同操作但向前移动,不需要递归。递归地做它确实会使代码更加优雅。

答案 1 :(得分:0)

使用堆栈进行前序遍历的关键思路是推右孩子然后离开孩子,这样左孩子就会在右孩子之前得到处理。

modelBuilder.Entity<BigAwesomeDinosaurWithTeeth>()
    .HasMany(e => e.YummyPunyPrey)
    .WithOne(e => e.BigAwesomeDinosaurWithTeeth)
    .OnDelete(DeleteBehavior.SetNull); // or whatever you like