字典树(Trie)
- 字典树,顾名思义,是关于“字典“的一棵树。也就是一种对于字典的一种存储方式(一种数据结构)。而这个词典中的每一个单词就是从根节点出发一直到某一个目标节点的路径,路径中每条边的字母连起来就是一个单词。
如图:
橙色代表目标节点所以这棵字典树上的单词有:
a
abc
bac
bbc
ca
- 字典树的本质就是把很多字符串拆成单个字符的形式,以树的方式存储起来。
- 字典树有两种基本操作分别是建树和查询。建树的操作就是把一个新单词插入到字典树里。查询操作就是查询给定单词是否在字典树上。
- 插入:
字典只包括26个字母,所以他的广度是可以提前确定好的,对于每一个节点,广度最大为26(因为每一个节点的下一个字母(即后缀点)只可能是26个字母)。但是这棵树的深度会因为具体的单词不一样来确定。
struct node
{
int nxte[27];
}trie[maxn];//开一个包含26个后缀指针的结构体
int num=0;
int insert(char s[],int id)
{
int now=0;//表示指向当前节点编号的一个指针
int len=strlen(s);
for(int i=0;i<len;i++)
{
int ch=s[i]-'a'+1;
if(!trie[now].nxt[ch])
{
trie[now].nxte[ch]=num;//表示点的编号
num++;
}
now=trie[now].nxte[ch];
}
end[now]=id;//表示当前单词的"目标节点"即单词结尾的那个节点具体是哪个单词的词尾
}
- 查询:
对于需要查询的字符串的当前字符,如果这个对应的字符指针为空,就说明不含这个单词,直接跳出。当我们都迭代完成后,直接返回end[now]。
int find(char s[])
{
int len=strlen(s);
int now=0;
for(int i=0;i<len;i++)
{
int ch=s[i]-'a'+1;
if(!trie[now].nxte[ch])
return 0;
}
return end[now];
}