在树的节点上构建等价类的好数据结构是什么?

时间:2009-03-23 19:17:20

标签: algorithm language-agnostic data-structures tree equivalence-classes

我正在寻找一个好的数据结构来在树的节点上构建等价类。在理想的结构中,以下操作应该是快速的(适当的O(1)/ O(n))和容易(没有神秘代码的段落):

  • (A)从树上走树;在每个节点上 - >子转换枚举子节点的所有等效版本
  • (B)合并两个等价类
  • (C)从现有节点(子节点)和其他数据列表中创建新节点
  • (D)查找结构上等同于节点的任何节点(即它们具有相同数量的子节点,相应的子节点属于相同的等价类,并且它们的“其他数据”相等)以便新的(或新修改的)节点可以放在正确的等价类(通过合并)

到目前为止,我已经考虑过(其中一些可以组合使用):

  • parfait,其中子节点引用节点集合而不是节点。 (A)速度快,(B)需要遍历树并更新节点以指向合并集合,(C)需要查找包含新节点的每个子节点的集合,(D)需要遍历树
  • 按特征维护节点的哈希值。这使得(D)更快但(B)更慢(因为当合并等价类时必须更新散列)
  • 将节点串在一起成为循环链表。 (A)速度很快,(B)会很快但是因为圆形列表的“合并”部分实际上会拆分列表(C)会很快,(D)需要走树#
  • 与上面一样,但每个节点都有一个额外的“向上”指针,可用于查找循环列表的规范成员。

我错过了一个甜蜜的选择吗?

3 个答案:

答案 0 :(得分:4)

我认为任何一种结构都不会解决您的问题,但您可能会看一下Disjoint-set data structure。毕竟,等价类与集合的分区是一样的。它应该能够快速处理其中一些操作。

答案 1 :(得分:4)

你似乎有两种形式的等价来处理。简单等价(A),作为等价类跟踪,保持最新和结构等价(D),你偶尔会建立一个等价类,然后扔掉它。

在我看来,如果你保持简单和结构等价的等价类,问题在概念上会更简单。如果这为结构等价引入了太多的流失,则可以为结构等价的某些方面维护等价类。然后,您可以找到一个平衡点,您可以负担维护这些等价类的要求,但在构建结构等效节点列表时仍然可以大大减少要检查的节点数。

答案 2 :(得分:2)

退后一步,我建议不要使用树。上次我不得不面对类似的问题,我开始用一棵树,但后来搬到了一个阵列上。

原因是多个,但最重要的原因是性能,我的多达100个孩子的类在将它们作为数组操作时实际上比通过树的节点更好地执行,主要是因为硬件局部性和CPU预取逻辑和CPU流水线。

因此,虽然在算法上数组结构需要比树更大的N次操作,但执行这些操作可能比在内存中追逐指针更快。