在C ++中创建trie / suffix树时减少内存使用量

时间:2013-08-08 20:48:56

标签: c++ algorithm tree

我正在尝试用c ++编写一个trie,现在我的基本数据结构是......

struct node{
    int count; no of times this node has been visited.
    struct node* child[ALPHABET_SIZE]; // Let ALPHABET_SIZE be 26
}

当字符串大小变大时,浪费了大量分配的内存。就像我们插入"he"一样 我们的树将是

root---->h--->e
    |--->e

我们看到在root用户只使用了2/26th分配的内存。 如何改进?

3 个答案:

答案 0 :(得分:2)

一些非常基本的建议:

  1. 如果您的分支因子预计较低,请考虑为孩子使用数组以外的其他内容。例如,您可以拥有一个字母到节点*对的数组,并对它们进行线性或二进制搜索(如果它们是有序的)。您还可以使用某种地图。
  2. 如果您不希望计数数百万/十亿,您还可以使用较小的整数来计算。
  3. 您可以从基于竞技场的分配器(即对象池)中获取节点,而不是动态分配节点,从而避免经常添加到堆上分配的对象的堆分配开销。

答案 1 :(得分:0)

在插入子节点时,不是为每个节点创建一个固定大小的数组,而是创建一个包含1个元素的数组并调整其大小(将其替换为大小为+ 1的新数组)。插入速度较慢,因此您可以测试并更改调整大小算法(大小+ 1或大小* 2或大小+大小/ 2),以便在速度过慢时分配更少。

答案 2 :(得分:0)

使用adjacency list

我们可以创建节点列表,而不是树。一个节点将是字典,每个字典都具有“当前值”(字母)和“下一个状态”(子节点的索引列表)。我们可以在节点中添加其他必需属性。

在您的情况下: 该列表将是-

  

[{“ value”:“”,“ next_state”:[1]},{“ value”:“ h”,“ next_state”:[2]},   {“ value”:“ e”,“ next_state”:[]}]

现在说,我们加上“他的”。该列表将更新为:

  

[{“ value”:“”,“ next_state”:[1]},{“ value”:“ h”,“ next_state”:[2,3]},   {“ value”:“ e”,“ next_state”:[]},{“ value”:“ i”,“ next_state”:[4]},{“ value”:“ s”,“ next_state”:[] },]

注意,索引1中的节点next_state。我们有两个子节点-“ e”和“ i”。

这是非常高效且易于实现的。但是,trie操作将相当慢。