Tire树,也叫做字典数,是一种存储字符串集合的方式。比起用二维数组之类的存储方法,Trie树的储存方法更加节省空间,而且在存储和查找的过程中,也十分的高效。
看似很厉害的东西,其实理解和学习起来并不算难,下面就一起康康,Trie树的存储方式以及代码的实现吧QwQ
1. Trie树的存储方式
顾名思义,Trie树既然是一种树,那么它的存储方式就一定是和树有关的。
Tire树的存储,其实就是建立一棵完全由字符组成的一棵树,树的深度也对应表示着字符串的长度。在储存一个新的字符串时,我们从根节点的子节点开始找起,看子节点中有没有已经存储了与字符串中的第一个字符相同的字符,如果有,就直接跳到那个字符的位置上,如果没有,就建立一个新的节点。
直接像这样说是很难理解的,所以我们来模拟一下这个过程。在Trie树中,存储“abcde”,“abcdf”,“abc”
“bcdf”四个字符串。
首先,我们把第一个字符串,“abcde”放入树中。因为这时候树是空的,所以所有节点都是新建的
就像这样,再在这个字符串的末尾做上标记,然后开始存入第二个字符串“abcdf”
就像这样,因为一直到‘d’时,两个字符串才出现差别,所以再加一个指向‘f’的分支就可以了。
然后接着插入“abc”
因为“abc”这三个字符在之前的树中都按顺序出现过了,也就是说这个字符串是之前插入过的字符串的子串,我们就直接在这个字符 串的结尾位置做上标记就好了。
最后加入“bcdf”
因为以‘b’开头的字符串我们还没遇见过,所以我们直接从根节点创建一个新的分支。
就这样,我们可以把很多字符串变成一个树存储起来。但是这样的储存方式必须保证树的分支不能太多,所以一般用Tire树的前提是要保证我们字符串中的不同字符个数是较少的。一般,我们可以用Trie树来存储英文单词,数字这些不过字符个数较少的字符串。
2. Tire树的代码实现
理解了上面的原理,代码实现也就是理解对应的步骤然后记忆模板就好了,所以我们直接来康Tire树的模板。
const int N = 100010;
int son[N][26], idx; // 这里我们举例存储字母‘a’ - ‘z’,son指向子节点,idx代表下标
int vis[N] // 用来标记字符串的结尾
void insert(char str[]) // 字符串的插入
{
int p = 0;
for(int i = 0; str[i]; i ++)
{
int u = str[i] - 'a';
if(!son[p][u]) son[p][u] = ++ idx; // 如果没找到,插入新节点
p = son[p][u]; // 跳到下个节点的位置
}
vis