【问题标题】:Optimal data structure for lookup within nested scopes在嵌套范围内查找的最佳数据结构
【发布时间】:2014-03-24 13:09:38
【问题描述】:

比如说,有一个树形数据结构,它的每个叶子都定义了一组用于查找的键:

*
|- A = 1, B = 2
|- *
   |- C = 4
   |- *
      |- D = 5
      |- D = 6, E = 7

我需要一种在深度优先遍历树时找到任何给定叶子的键值的方法。

我想到了两种方法:

  1. 如果在当前叶子中找不到该值,则检查其父级的字典,依此类推回到树的根。

  2. 有一个全局字典,每个叶子在被遍历时插入/删除它的键。在此全局字典中执行的查找。

很可能会有很多叶子,每个叶子都有几个键,每个键大约需要 3-4 次查找。

哪种方法更有效?或者,也许有另一种比两者都更好的方法?

【问题讨论】:

  • 几个问题:为什么要深度优先?树的数量是多少(二元、三元……)?节点的键与其叶子的键之间有什么关系?从某个角度来看,您可能正在寻找B-tree
  • @OndrejTucny,考虑一些编程语言的简单编译器。节点 = 可见范围,键 = 变量名。因此,每个节点可以有任意数量的子节点。这也解释了遍历顺序。需要的是从任何嵌套的子作用域中查找变量的最快方法。

标签: c# dictionary compiler-construction tree lookup


【解决方案1】:

您正在实施的编程语言肯定会定义名称解析的确切规则。我认为这不会导致深度优先搜索。名称解析规则,非常频繁,看起来像这样:

  1. 搜索当前范围,经常只考虑源代码中从当前位置声明“向上”的内容;
  2. 当满足某些特定规则时,例如有某种形式的 using / import 或任何其他构造链接到某个其他范围,在该其他范围中执行搜索(所有这些范围,顺序),并在其中递归:
    1. 搜索给定范围,
    2. 递归任何相关的嵌套范围;
  3. 转到立即封闭的范围;
  4. 从 (1) 重复,其中“当前”范围是 (3) 中确定的范围。

换句话说,您逐渐在封闭范围树中向上,并决定是否搜索任何“外部”引用范围。诸如using / import 之类的语句会导致作用域之间的引用,进而导致被视为作用域树的内容实际上是有向图。

关于查找表的构造,我将从一个简单的哈希表开始。 Prefix trees (tries) 也适用于这些场景。

最后但同样重要的是,我不会太在意查找性能,除非在编译数万或数十万行代码时遇到真正的性能问题。

【讨论】:

  • 感谢您的回复!这不是真正的深度优先搜索,而是深度优先遍历顺序(其中节点被解析、验证然后以字节码发出),但查找过程是相反的。无论如何,您可能是对的,在这种特殊情况下的优化不会影响整体性能,所以我将实现更简单的那个。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-13
相关资源
最近更新 更多