如果我有一个树结构,其节点可以有零到多个子节点,每个节点都有一个数据值和一个布尔开关,那么对于具有特定开关值的节点,我该如何最小地表示该树的状态?
例如,假设我的树看起来像:
A[0] -> B[1] -> C[1]
|-----> D[1]
|-----> E[1]
这里我们有一个状态,其中检查了4个节点,有没有办法以简洁的方式表示这个状态?天真的方法是列出四个节点被检查,但是如果节点B有100个孩子而不是四个孩子呢?
我目前的想法是将每个节点的祖先存储在数据组件中,并根据最小化表示状态所需数据的祖先集来描述已检查状态。在下面的树中,节点N的祖先表示为n'。所以上面的树现在看起来像:
A[0, {a}] -> B[1, {a', b}] -> C[1, {a' b' c}]
|--------------> D[1, {a' b' d}]
|--------------> E[1, {a' b' e}]
现在,您可以分析树并查看所有节点A的子节点都已被检查,并将状态简单描述为具有数据元素a'的节点设置为1或仅[a']。如果节点D的状态切换为0,则可以将树状态描述为[a'not d]。
是否有可用于解决此类问题的数据结构或算法?有关更好方法的任何想法?有关分析算法的任何想法吗?
由于
答案 0 :(得分:2)
使用从根开始的预订树遍历。如果检查节点,则不要遍历其子节点。对于每个遍历的节点存储,它在布尔位图(8位/字节)中检查状态(布尔值0/1)。最后使用zip / bzip或任何其他压缩技术压缩结果。
重建状态时,首先解压缩,然后使用预序树遍历,根据状态设置每个节点,如果选中状态则将所有子节点设置为已选中并跳过它们。
答案 1 :(得分:0)
通常,没有技术总是能够将检查的元素存储在少于n位的空间中,其中n是树中元素的数量。这背后的基本原理是有2 ^ n个不同的可能检查状态,因此您需要至少2 ^ n个不同的编码,因此必须至少有一个长度为2 ^ n的编码,因为只有2 ^ n - 1个编码比这短。
鉴于此,如果你真的想要最小化空间使用,我建议使用像@yi_H建议的编码。它为每个编码精确使用n位。您可以通过对这些位应用标准压缩算法来压缩大多数编码,对于实际的已检查节点集可能会做得很好,但在最坏的情况下会优雅地降级。
希望这有帮助!