字典树

字典树定义:

字典树,又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种。典型应用是应用于统计、排序和保存大量的字符串(但仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高。

字典树与字典很相似,当你要查一个单词是不是在字典树中,首先看单词的第一个字母是不是在字典的第一层,如果不在,说明字典树里没有该单词,如果在就在该字母的孩子节点里找是不是有单词的第二个字母,没有说明没有该单词,有的话用同样的方法继续查找.字典树不仅可以用来储存字母,也可以储存数字等其它数据。

字典树性质:

  1. 根节点不包含字符,除根节点外每一个节点都只包含一个字符;
  2. 从根节点到某一结点,路径上经过的字符连接起来,为该节点对应的字符串;
  3. 每个节点的所有子节点包含的字符都不相同。

字典树的应用:

  • “串”的快速检索:给出N个单词组成的熟词表,以及一篇全用小写英文书写的文章,请你按最早出现的顺序写出所有不在熟词表中的生词。可以用数组,枚举,用哈希,用字典树,先把熟词建一棵树,然后读入文章进行比较,这种方法效率是比较高的。

  • “串”的排序:给定N个互不相同的仅由一个单词构成的英文名,让你将他们按字典序从小到大输出。用字典树进行排序,采用数组的方式创建字典树,这棵树的每个结点的所有儿子很显然地按照其字母大小排序。对这棵树进行先序遍历即可。

  • 最长公共前缀:对所有串建立字典树,对于两个串的最长公共前缀的长度即他们所在的结点的公共祖先个数,于是,问题就转化为当时公共祖先问题。

Trie树模板:

Trie的数据结构定义:

const int MAX = 26;

struct Trie {
    //v表示一个字典树到此有多少相同前缀的数目。
    int v;
    //next表示每层有多少种类,如果只是小写字母,则26即可。如为大小写字母,则52,若再加上数字,则是62。
    Trie* next[MAX];
};

Trie root;

生成Tire树:

void creatTrie(char *str) {
    int len = strlen(str);
    Trie* p = &root, *q;
    for(int i = 0; i < len; ++i) {
        int id = str[i] - 'a';
        if(p->next[id] == NULL) {
            q = (Trie*)malloc(sizeof(root));
            //v初始为1,即指当前。
            q->v = 1;
            for(int j = 0; j < MAX; ++j) {
                q->next[j] = NULL;
            }
            p->next[id] = q;
            p = p->next[id];
        } else {
            p->next[id]->v++;
            p = p->next[id];
        }                
    }    
}

查找:

int findTrie(char *str) {
    int len = strlen(str);
    Trie* p = &root;
    for(int i = 0; i < len; ++i) {
        int id = str[i] - 'a';
        p = p->next[id];
        if(p == NULL) {
            return 0;
        }
    }
    return p->v;
}

results matching ""

    No results matching ""