读书人

Trie树/字典树的简介及兑现

发布时间: 2012-11-06 14:07:00 作者: rapoo

Trie树/字典树的简介及实现
Trie树|字典树的简介及实现

1综述

又称单词查找树Trie树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。

它的优点是:利用字符串的公共前缀来节约存储空间,最大限度地减少无谓的字符串比较,查询效率比哈希表高。

Trie树结构的优点在于:

1) 不限制子节点的数量;

2) 自定义的输入序列化,突破了具体语言、应用的限制,成为一个通用的框架;

3) 可以进行最大Tokens序列长度的限制;

4) 根据已定阈值输出重复的字符串;

5) 提供单个字符串频度查找功能;

6) 速度快,在两分钟内完成1998年1月份人民日报(19056行)的重复字符串抽取工作。

优点来源于Linux公社网站(www.linuxidc.com)http://www.linuxidc.com/Linux/2012-04/57911.htm

2性质

它有3个基本性质:

1) 根节点不包含字符,除根节点外每一个节点都只包含一个字符。

2) 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。

3) 每个节点的所有子节点包含的字符都不相同。

3基本操作

其基本操作有:查找、插入和删除,当然删除操作比较少见.我在这里只是实现了对整个树的删除操作,至于单个word的删除操作也很简单.

4实现方法

搜索字典项目的方法为:

  (1) 从根结点开始一次搜索;

  (2) 取得要查找关键词的第一个字母,并根据该字母选择对应的子树并转到该子树继续进行检索;

  (3) 在相应的子树上,取得要查找关键词的第二个字母,并进一步选择对应的子树进行检索。

  (4) 迭代过程……

(5) 在某个结点处,关键词的所有字母已被取出,则读取附在该结点上的信息,即完成查找。

其他操作类似处理

5. Trie原理——Trie的核心思想是空间换时间。利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。

6.代码实现

const int branchNum = 26; //声明常量int i; struct Trie_node{       boolisStr;                //记录此处是否构成一个串。       Trie_node*next[branchNum];//指向各个子树的指针,下标0-25代表26字符       Trie_node():isStr(false)       {              memset(next,NULL,sizeof(next));       }}; class Trie{ public:     Trie();     voidinsert(const char* word);     boolsearch(char* word);     voiddeleteTrie(Trie_node *root);       // voidprintTrie(Trie_node *root);   //new add private:    Trie_node* root; }; Trie::Trie(){     root =new Trie_node();} void Trie::insert(const char* word) {    Trie_node*location = root;   while(*word)     {       if(location->next[*word-'a'] == NULL)//不存在则建立         {           Trie_node *tmp = new Trie_node();           location->next[*word-'a'] = tmp;        }          location = location->next[*word-'a']; //每插入一步,相当于有一个新串经过,指针要向下移动       word++;    }   location->isStr = true; //到达尾部,标记一个串 } bool Trie::search(char *word){       Trie_node*location = root;       while(*word&& location)       {              location= location->next[*word-'a'];              word++;       }       return(location!=NULL && location->isStr); } void Trie::deleteTrie(Trie_node *root){       for(i =0; i < branchNum; i++)       {              if(root->next[i]!= NULL)              {                     deleteTrie(root->next[i]);              }       }       deleteroot;} void main() //简单测试{       Trie t;       t.insert("a");               t.insert("abandon");        char * c= "abandoned";       t.insert(c);       t.insert("abashed");        if(t.search("abashed"))       {          printf("true\n");  //已经插入了       }}

读书人网 >编程

热点推荐