字典树

字典树

字典树可以解决词频统计、前缀是否重复等问题。
如图,我们可以对cat,cash,apple,aply,ok建一棵字典树

1.png

由此可以看出:

1、字典树用边表示字母

2、有相同前缀的单词公用前缀节点,那我们可以的得出每个节点最多有26个子节点(在单词只包含小写字母的情况下)

3、整棵树的根节点是空的。为什么呢?便于插入和查找,这将会在后面解释。

4、每个单词结束的时候用一个特殊字符表示,图中用的‘′,那么从根节点到任意一个‘′,那么从根节点到任意一个‘’所经过的边的所有字母表示一个单词。


基本操作

1.insert 插入单词进字典树
这里有两种方法,一种是用指针实现,一种使用数组实现。相比较指针,数组实现速度会比较快,这里先写一下数组实现字典树的方式。

void insert(string str)
{
    int len = strlen(str);   //获得待插入单词的长度
    int tr = 0;   //从根出发
    for(int i=0;i<len;i++)
    {
        int k = str[i] - 'a';
        if(!trie[tr][k])  //如果没有这条边,则新建
        {
            trie[tr][k] = ++tot;  //给新的节点编号
        }
        //trie[tr].mark = true 如果要判断单词
        tr = trie[tr][k]; //向下延伸
    }
}

2.查找一个前缀(整个单词)
只需要从根出发,判断能不能一直走到所给单词的末尾就行了。如果要判断是否是一个完整的单词,在建树的时候要给单词末尾加标记。

bool search(string str)
{
    int len = str.length();
    int tr = 0;
    for(i=0;i<len;i++)
    {
        int k = str[i] - 'a';
        if(!trie[tr][k])
        {
            return false;  //无法向下走下去了,说明没有这个前缀
        }
        tr = trie[tr][k];
    }
    return true; //走到单词末尾了,说明查找到了
}

留坑

... ... ...