在Java中实现数据结构空间使用

时间:2015-02-27 21:21:22

标签: java algorithm trie space-complexity

我只想仔细检查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;
     }
}

2 个答案:

答案 0 :(得分:4)

如果单个节点的内存占用是K个引用,并且trie有N个节点,那么它的空间复杂度显然是O(N * K)。这解释了空指针占据其空间的事实。实际上,数组条目是null还是任何其他值都不会改变内存消耗方面的任何内容。

O(K ^ L)是完全不同的度量,因为它使用不同的参数。基本上,K ^ L是对人口稠密线索中节点数量的估计,而在O(N * K)中,明确给出了节点数。

答案 1 :(得分:0)

我想提供更多关于 Marko's answer 的细节。

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

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

您可以知道的是 L(键的平均长度)和 K(字母表的大小),因此您可以使用这些来分析复杂度。如果你进行数学计算,你会发现 K^L 实际上只占特里树的最后一层(取 K=2L=3,这将给出高度为 4 的二叉树,并且2^3 = 最后一层有 8 个节点,总共 15 个节点)。最后一层没有给出树中节点的总数,但我们谈论的是渐近分析,只有重要的位才重要。所以你有 O(K^L)