如何更有效地将有序树编码为比特序列

时间:2012-02-08 21:18:21

标签: algorithm data-structures tree

假设我们要保存n个节点的有序树的形状,每个节点最多有2个子节点。 如果它是二叉树,我们必须使用2n位。因为在我们的情况下,我们没有左或右孩子,他们是相同的,所以我们必须有一些冗余的序列。 那么,我们能以更好的方式对其进行编码吗?似乎每个节点仍然有3个案例,没有孩子,一个孩子,两个孩子,但我们可以将它存储在少于2位吗?或者总共有一个比2更好的常数?

3 个答案:

答案 0 :(得分:1)

您可以在提及时存储2n位,然后使用huffman coding或其他lossless data compression技术压缩此数据。

我认为你不能达到更好的最坏情况,但在一般情况下 - 它应该为你节省一些空间。

答案 1 :(得分:1)

有两种方法可以解决它:

  1. 对多级子树进行编码。例如:在最高级别2,您可以具有四种形状:(),(a),(a-> b)和(a< -b-> c)。现在每个案例使用0,10,110,111。对于简单的2级完整树编码是:111 0 0. 3级完整树是:111,10,10。对于4级完整树,这变为:111 111 111 0 0 0 0。作业是任意的。您可以使用霍夫曼编码方案(如提到的那样)来找到最佳编码。对于链,这种编码方案更糟糕。对于纯链,您需要3n-2位才能存储。

  2. 进行2n位编码,然后使用任何压缩算法进行压缩。

  3. ===另一种方法===

    在每个节点的正常表示中,您可以使用以下三个选项之一:00,01,11。现在,一次取三个节点。您可以拥有27种组合。您可以将这些组合中的每一个存储为5位。这样,所需的平均存储量变为5/3而不是2位。此外,您可以尝试组合任意数量的节点。请参阅下表了解压缩率:

    如您所见,如果将10个节点组合在一起,则会将存储空间减少1.25倍(即空间减少20%)

    naive_length compr_length compr_factor
    2 2 1.0
    4 4 1.0
    6 5 1.2
    8 7 1.14285714286
    10 8 1.25
    12 10 1.2
    14 12 1.16666666667
    16 13 1.23076923077
    18 15 1.2
    20 16 1.25
    22 18 1.22222222222
    24 20 1.2
    26 21 1.2380952381
    28 23 1.21739130435
    30 24 1.25
    32 26 1.23076923077
    34 27 1.25925925926
    

答案 2 :(得分:0)

如果我理解正确,如果一个节点有一个孩子,那么它不是左或右孩子,即如果是一个孩子,你就不能区分左右。然后我认为它可以在(log 3)n中完成,其中日志是基数2。

通过前序遍历描述树,为每个节点编写子项数(0,1或2)。这会创建一个长度为n的基数3(实际上长度为n - 1,最后一个节点将始终为零个子节点)。正好有3 ^(n - 1)个这样的数字,这可以在(log 3)(n - 1)〜= 1.59(n - 1)中以二进制编码。

可以使用O(log n)位来编写编码位串开头的位数。

更新:此处为implementation