目录
引言
在计算机科学中,Trie(字典树)是一种高效的数据结构,通常用于高效的存储和检索字符串集合。它通过利用字符串之间的公共前缀,提供了快速的查找和插入操作。本文将介绍 Trie 的基本概念、结构和应用场景,并通过示例代码来解释它的使用方法。
1、基础概念
我们先来看一个完整的树大概是什么样子的:
我们可以看到,树的结构就是从最上面的节点一直产生分支,不断产生新的节点,此时,我们需要知道,在数树结构中,存在这样两个名词:根节点(root),子节点(child node)
提取出最上面三个节点,我们可以在树形结构中如下图所示:
其实对于最上面的A节点来说,下面的所有节点(B、C、D、E、F、G、H、I、J、K、L、M、N、O)都是A的子节点
为什么这么说?我们不妨想象一下,如果在某一情况下,当B作为根节点呢?很显然,B以下的部分(D、E、H、I)就都是B的子节点
因此,关于根节点和子节点的位置,是通过某一状态来判断的,切不可单纯认为最上面的就是根节点,下面都是子节点,永远不会变了。
2、字典树的存储
比如我们要在Trie中存储这样的字符串集合,用字典的方式
abcdef
abdef
aced
bcdf
bcff
cdaa
bcdc
当我们需要将这些字符存入到一颗树中,我们可以从第一个字符串开始,从第一个根节点开始存储。
首先在一开始,我们的树是空的,只存在一个root根节点(可以视为一直存在),然后当我们从第一个字符串的第一个字母开始存储时,我们会率先查找树的两个子节点是否已经存储过这个字符,如果没有,我们就创建一个子节点来存储这一个字符,如果有,我们就转移到树的存储该字符的那一个节点上,以它为新的根节点,然后开始存储第一个字符串的第二个字符......
我们画图演示一下:(在存储时,默认先左节点再右节点)
存储abcdef: 存储abdef:
存储aced时: 存储bcdf时:
存储bcff时: 存储cdaa时:
存储bcdc时:
我们将完整的树画下来:
至此,我们的字符串集合已经全部存入到这一颗树当中去了,并且我们可以发现,字符串集合中的每一个字符串,都可以在树中通过对应的路径得到。
下面,我们需要对最后一层节点做一个标记:
有什么作用呢?他表示的是在字符串集合中,每一个字符串结尾的位置。
我们回到刚刚每一条字符串,然后依次在树中进行查找,可以发现每一个字符串的结尾,在这一棵树中都是最后一层的位置,也就是说,我们可以通过这些标记过的位置往回走,一样可以得到原来的字符串。
也许还有人不理解,我们假设我们现在有一个abc的字符串,那我们就可以按照这个路径找到:
那么此时,我们就要对字符串末尾的位置打上标记:
也就是说,只要字符串末尾的字符的标记存在,那么这条字符串的路径必然存在
3、字典树的查找
当我们构建出树结构后,我们可以通过树的路径来查找某一个字符串是否存在,或者说这个字符串出现过了几次。
假设我们要在上面的那棵树中寻找aced
很明显我们可以通过这样的路径找到,并且最后一个节点是有标记的:
但是若是我们要寻找abcf,那很明显,根据同样的道理,我们是找不到的,因为当我们在路径的
a->b->c时,c此时作为根节点,无法找到子节点 f 的存在。
另外还有一种情况,可以详细的描述标记的作用:查找abcd是否存在字符串集合中?
在我们的树中,abcd虽然是可以被找到的,如图:
但是!!! 我们发现在d的位置,我们并没有标记过,也就是说在原来的字符串集合中,并没有abcd这样的字符串存在,所以无法查找到该字符串。
例题:字符串统计——Acwing
代码:
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=1e5+10;
int son[N][26],cnt[N],idx;
char str[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];
}
cnt[p]++;
}
int query(char str[]){
int p=0;
for(int i=0;str[i];i++){
int u=str[i]-'a';
if(!son[p][u]) return 0;
p=son[p][u];
}
return cnt[p];
}
int main(){
int n;
cin>>n;
while(n--){
char op[2];
cin>>op>>str;
if(op[0]=='I') insert(str);
else cout<<query(str);
}
return 0;
}
对于上面的代码,下面给到一个Acwing学员的精彩评论!~~~