关于字典树节点数组大小问题

问题描述

对于分支数为 w w w的字典树(前缀树),插入 n n n个字符串,每个字符串长度最大 m m m,那么字典树节点数组需要开多大合适?(使用静态开辟空间,排除vector等动态开辟空间的方法)

结论

k = ⌊ l o g w n ⌋ k=\lfloor log_{w}n \rfloor k=logwn,那么数组大小 t o t l e = w ( w k − 1 ) / ( w − 1 ) + ( m − k ) ∗ n ≤ w ∗ ( n − 1 ) w − 1 + ( m − k ) ∗ n totle=w(w^k-1)/(w-1)+(m-k)*n \le \frac {w*(n-1)}{w-1}+(m-k)*n totle=w(wk1)/(w1)+(mk)nw1w(n1)+(mk)n

这个可能有些复杂, 我们开数组大小一般也不会这样再计算一下。

其实一般我们把数组大小开到 m ∗ n m*n mn个即可,显而易见这个大小是足够的,假设在最坏的情况下,我们再坏一些,这些字符串的每个前缀都不同,那么都占用一个节点,这样的不同的前缀的个数是 m ∗ n m*n mn(但是都不会这么大)。

证明

我们的数组大小必须能够在最坏情况下足够使用。最坏情况下我们假设每个字符串的长度都是最长的m,因为两个前缀相重复的越多,那么就会省下的空间就越多,所以我们尽量让这些字符串的前缀不同。

因为有n个字符串,假设这n个字符串都不相同,那么形成的字典树叶子节点的个数就是n。

最坏情况下,我们形成的字典树会有这样一个特征:存在一个深度k,使得深度 [ 1 , k ] [1,k] [1,k] 的都是满叉(根节点的深度是0),且深度 [ k + 1 , m ] [k+1,m] [k+1,m]中每层的节点数量都是 n n n。(因为长度为 x x x情况下,不同的前缀数量最多为 m i n ( n , w x ) min(n,w^x) min(n,wx)个)

不难理解 k k k是满足条件 w k ≤ n w^k\le n wkn下的最大值,故 k = ⌊ l o g w n ⌋ k=\lfloor log_{w}n \rfloor k=logwn,故总结点数量 t o t l e = w + w 2 . . + w k + ( m − k ) ∗ n totle=w+w^2..+w^k+(m-k)*n totle=w+w2..+wk+(mk)n

化简可得

t o t l e = w ( w k − 1 ) / ( w − 1 ) + ( m − k ) ∗ n ≤ w ∗ ( n − 1 ) w − 1 + ( m − k ) ∗ n totle=w(w^k-1)/(w-1)+(m-k)*n \le \frac {w*(n-1)}{w-1}+(m-k)*n totle=w(wk1)/(w1)+(mk)nw1w(n1)+(mk)n

你可能感兴趣的:(#,字典树)