字典树是一种存储字符串的高效的结构,它保存了不同字符的相同前缀,又因此叫做前缀树,使用前缀,大大避免相同字符的重复匹配,加快查找效率
- 字典树是一颗多叉树,比如存储26个字母的,那么就有26叉
- 字典树的节点不存储字符,而是用树的边来存储字符
- 字典树的每一个节点都对应着一个字符子串
- 字典树的叶子节点对应的字符串是创建字典树的字符串集合里的元素
如图:使用 5 个字符串创建字典树,蓝色节点代表子串,红色节点表示集合里的字符串(或者说字典树的叶子节点表示完整的字符串)
["apple", "apk", "kksk", "kkp", "boki"]
结构定义
可以快速的定义一个26叉树
/*
isEnd 表示是否是叶子节点
s 表示当前节点代表的字符串
*/
class node
{
public:
bool isEnd;
string s;
node* childs[26];
node(){
s=""; isEnd=false; for(int i=0; i<26; i++)childs[i]=NULL;}
};
插入元素
对于长度为n的字符串,我们依次遍历元素,从根节点开始,比如第一个字符是 ‘a’,那么查找根节点是否有 ‘a’ 的子树
- 如果有,转到那个子树
- 如果没有,创建新的子树,再转到
最后遍历结束时,记得把叶子节点的 isEnd 置一
void insert(node* &root, string s)
{
node* p = root;
for(int i=0; i<s.length(); i++)
{
if(p->childs[s[i]-'a']) p=p->childs[s[i]-'a'];
else
{
node* nd = new node();
nd->s = p->s + s[i];
p->childs[s[i]-'a'] = nd;
p = nd;
}
}
p->isEnd =