想象一下下面的树:
A
/ \
B C
/ \ \
D E F
我正在寻找一种方法来查询例如 F 是否是 A 的后代(注意:F 不需要是 A 的直接后代),在这种特殊情况下是正确的。只有有限数量的潜在父节点需要针对更大的潜在后代节点池进行测试。
在测试一个节点是否是潜在父池中某个节点的后代时,需要针对所有潜在父节点进行测试。
这是一个想出的:
将多路树转换为特里树,即为上述树中的每个节点分配以下前缀:
A = 1 B = 11 C = 12 D = 111 E = 112 F = 121
然后,为每个可能的前缀大小保留一个位数组并添加要测试的父节点,即如果将 C 添加到潜在的父节点池中,请执行以下操作:
1 2 3 <- Prefix length *[1] [1] ... [2] *[2] ... [3] [3] ... [4] [4] ... ... ...
当测试一个节点是否是潜在父节点的后代时,取其 trie 前缀,在第一个“前缀数组”(见上文)中查找第一个字符,如果存在,则在第二个“前缀”中查找第二个前缀字符数组”等等,即测试 F 导致:
F = 1 2 1 *[1] [1] ... [2] *[2] ... [3] [3] ... [4] [4] ... ... ...
所以是的,F,是 C 的后代。
这个测试似乎是最坏情况 O(n),其中 n = 最大前缀长度 = 最大树深度,所以它的最坏情况完全等于直接上树并比较节点的明显方法。但是,如果测试的节点靠近树的底部并且潜在的父节点位于顶部的某个地方,则此方法的性能要好得多。结合这两种算法将减轻两种最坏的情况。但是,内存开销是一个问题。
还有另一种方法吗?任何指针都非常感谢!