【问题标题】:Trie data structure space usage in JavaJava中的Trie数据结构空间使用情况
【发布时间】:2015-02-27 21:21:21
【问题描述】:

我只是想仔细检查一下 Trie 数据结构在最坏情况下可能拥有的总空间。我认为这将是 O(N*K),其中 N 是节点总数,K 是字母表的大小(指向其他尝试),但人们一直告诉我这是 O(K^L),其中 K 是字母表的大小和 L 是平均字长,但是这些空指针会占用 Java 中的内存空间吗?例如,如果其中一个节点在总大小 K 中只有 3 个分支/点。它是否使用 K 空间?还是只有 3 个?以下是Java中的Trie实现@

class Trie {
     private Trie [] tries;

     public Trie () {
          // A size 256 array of Trie, and they are all null
          this.tries = new Trie[256]; // K = 256;
     }
}

【问题讨论】:

  • 我从未听说过使用 O(N^K) 空间的 trie,也没有看到任何理由这样做,无论空指针占用空间。
  • 可能您的意思是 a^m(其中 a 是字母的大小,m 是平均字长) - 请参阅 this answer 下的 cmets
  • @Shashank 对不起,我的意思是 K^N
  • 它可能是 K^L,其中 K 是字母大小,L 是 DNA 所说的平均字长。但不是 K^N,因为 N 是总节点数,远远超过平均字长。
  • @Shashank 你是对的。让我更正一下。

标签: java algorithm trie space-complexity


【解决方案1】:

如果单个节点的内存占用是K个引用,而trie有N个节点,那么显然它的空间复杂度是O(N*K)。这说明了空指针 do 占据了它们的空间。实际上,无论数组条目是 null 还是任何其他值,在内存消耗方面都不会发生任何变化。

O(K^L) 是一个完全不同的度量,因为它使用不同的参数。基本上 K^L 是对密集填充树中节点数的估计,而在 O(N*K) 中,节点数是明确给出的。

【讨论】:

  • 例如 Object[] obj_arr1 = {null, null, null, new Object(), new Object()} 使用与 Object[] 相同的内存 obj_arr2 = new Object[5]; ?
  • 数组,是的。这两个对象当然使用自己的内存,但它们不是数组内存的一部分。
  • “不是数组内存的一部分”是什么意思?
  • 我的意思是数组不包含任何对象。
  • 得到它...它只是携带指向实际对象的指针,对吗?
【解决方案2】:

我想详细介绍一下Marko's answer

trie的每个节点消耗的内存都是一样的,是null还是不是。数组只存储指针,并且它具有自初始化以来的总空间。每个节点虽然都有自己的内存,但这是一个实现细节,我们在谈论渐近分析,所以我们不考虑节点实现所占用的内存。

O(N*K) 是完整 trie 中的节点数(对于每个节点 NK 子节点)。这是正确的,但是您正在考虑节点的数量,而您事先并不知道。如果您知道这一点,您可以将每个节点使用的内存相加(实现细节),您将计算出 trie 使用的确切内存量。在这种情况下,Big-O 表示法甚至可能没有意义(?)。

您可以知道L(键的平均长度)和K(字母的大小),因此您可以使用它们来分析复杂性。如果你做数学,你会发现K^L实际上只占trie的最后一层(取K=2L=3,这将给出一个高度为4的二叉树,并且2^3 = 8个节点在最后一级,总共 15 个节点)。最后一个级别没有给出 trie 中的节点总数,但我们正在讨论渐近分析,只有有效位很重要。所以你有O(K^L)

【讨论】:

    猜你喜欢
    • 2022-01-01
    • 1970-01-01
    • 2011-04-17
    • 2018-09-27
    • 1970-01-01
    • 1970-01-01
    • 2018-03-20
    • 2011-05-23
    • 2021-11-11
    相关资源
    最近更新 更多