问题描述
对于分支数为w的字典树(前缀树),插入n个字符串,每个字符串长度最大m,那么字典树节点数组需要开多大合适?(使用静态开辟空间,排除vector等动态开辟空间的方法)
结论
令k=⌊logwn⌋,那么数组大小totle=w(wk−1)/(w−1)+(m−k)∗n≤w−1w∗(n−1)+(m−k)∗n
这个可能有些复杂, 我们开数组大小一般也不会这样再计算一下。
其实一般我们把数组大小开到m∗n个即可,显而易见这个大小是足够的,假设在最坏的情况下,我们再坏一些,这些字符串的每个前缀都不同,那么都占用一个节点,这样的不同的前缀的个数是m∗n(但是都不会这么大)。
证明
我们的数组大小必须能够在最坏情况下足够使用。最坏情况下我们假设每个字符串的长度都是最长的m,因为两个前缀相重复的越多,那么就会省下的空间就越多,所以我们尽量让这些字符串的前缀不同。
因为有n个字符串,假设这n个字符串都不相同,那么形成的字典树叶子节点的个数就是n。
最坏情况下,我们形成的字典树会有这样一个特征:存在一个深度k,使得深度[1,k] 的都是满叉(根节点的深度是0),且深度[k+1,m]中每层的节点数量都是n。(因为长度为x情况下,不同的前缀数量最多为min(n,wx)个)
不难理解k是满足条件wk≤n下的最大值,故k=⌊logwn⌋,故总结点数量totle=w+w2..+wk+(m−k)∗n
化简可得
totle=w(wk−1)/(w−1)+(m−k)∗n≤w−1w∗(n−1)+(m−k)∗n