一、定义
字典树,也称字母树,指的是某个字符串集合对应的有根树,树的每条边上恰好对应一个字符,每个顶点代表从根到该结点的路径所对应的字符串。Tire很好的利用了串的公共前缀,节省了存储空间。
二、基本操作
1.初始化。一个空Tire树仅包含一个根结点,该结点的字符指针均为空。
2.插入数据。当需要插入一个字符串s时,令一个指针p起初指向根结点,然后,依次扫描s中的每个字符c,
当指针p的c字符指针指向一个已经存在的结点q,令p=q。
当指针p的c字符指针指向空时,则新建一个结点q,使p的c字符指针指向q。然后令p=q。
当s中字符扫描完毕时,在当前结点指针p上标记它是一个字符串的末尾。
3.查询操作。查询字符串s是否在Tire中是否存在,我们令一个指针p起初指向根结点,然后依次扫描s中的每个字符。
当指针p的c字符指针指向空,说明s没有被插入过Tire树中,结束查询。
当指针p的c字符指针指向一个已经存在的结点q,则令p=q;
当指针s中的字符扫描完毕时,若当前结点p被标记成一个字符串的末尾,则说明s在Trie中已经存在,否则说明s在Tire中不存 在。
三、代码实现
前面描述都是用指针实现,不熟悉指针的可能看的很迷茫,下面的Tire树在代码中的实现都是用数组存储,比较简单易懂,建议看完数组的实现后,再重新理解上述内容。
1.Tire树的存储。用二维数组存字符串,令开一个数组表示其Tire中字符串。
int ch[N][Z];//N为结点个数,Z为字符集大小。
bool bo[N];//若bo[i]=true,则说明从根结点到结点i经过的边上字母组成的字符串在Tire中存在
2.向Tire树中插入字符串s。
int tot=0;
void insert(char* s){ //char* s传递一个字符数组。
int len=strlen(s);
int u=1; //u表示结点数,u=1表示根结点。
for(int i=0;i<len;++i){
int c=s[i]-'a'; //此处默认字符串s为小写字符串。
if(!ch[u][c])
ch[u][c]=++tot; //tot为总点数。
u=ch[u][c];
}
bo[u]=true; //代表一个实际字符串集合中的元素。
}
3.查询字符串s是否在Tire树中。
bool find(char* s){
int len=strlen(s);
int u=1;
for(int i=0;i<len;++i){
int c=s[i]-'a';
if(!ch[u][c])return false; //如果在Tire树中找不到c对应的结点
u=ch[u][c];
}
return true;
}
下一篇将讲解字典树Tire的具体应用。