字典树,又名Trier树,可以用于单词的查找和统计。

字典树的示例如下图所示,其中,若根节点为第0层,则第k层节点表示字典中单词前k个字符,从根节点至树中标黄节点的路径表示以该节点字符为末尾的单词,例如,too、tooth、tea、two等。 

字典树

字典树中的节点可用以下结构体表示:


  1. typedef struct TNode 
  2.     char value;//表示该节点存储的字符 
  3.     int count;//表示以该节点字符为末尾的单词出现的次数 
  4.     bool endFlag;//表示该节点是否是单词的末尾 
  5.     TNode* childList[26];//表示下一个字符 
  6. }TNode,*DTree; 

 字典树的初始化和插入单词操作:


  1. //初始化字典树 
  2. void Init(DTree &tree) 
  3.     int i; 
  4.     tree=(DTree)malloc(sizeof(TNode)); 
  5.     tree->value = ‘ ‘;//根节点的字符为空 
  6.     tree->count = 0; 
  7.     tree->endFlag = false
  8.     for (i=0;i<26;i++) tree->childList[i] = NULL; 
  9.  
  10. //将单词插入字典树中 
  11. //从根节点开始从上至下,将单词字符从左至右逐步插入到字典树中 
  12. void Insert(DTree tree,char string[],int len) 
  13.     int i,j; 
  14.     TNode* node = tree; 
  15.     for (i=0;i<len;i++) 
  16.     { 
  17.         //若节点存在,则直接访问下一个节点 
  18.         //若该节点是单词最后一个字符,则将endFlag置为true,并将count加1 
  19.         if (node->childList[string[i]-‘a’]!=NULL) 
  20.         { 
  21.             node = node->childList[string[i]-‘a’]; 
  22.             if (i==len-1)  
  23.             { 
  24.                 node->endFlag = true
  25.                 node->count++; 
  26.             } 
  27.         } 
  28.         //若节点不存在,则新建节点并初始化 
  29.         //若该节点是单词最后一个字符,则将endFlag置为true,否则置为false,并将count加1 
  30.         else 
  31.         { 
  32.             node->childList[string[i]-‘a’] = (TNode*)malloc(sizeof(TNode)); 
  33.             node = node->childList[string[i]-‘a’]; 
  34.             node->value = string[i]; 
  35.             for (j=0;j<26;j++) node->childList[j] = NULL; 
  36.             node->endFlag = false
  37.             if (i==len-1)  
  38.             { 
  39.                 node->endFlag = true
  40.                 node->count++; 
  41.             }            
  42.         } 
  43.     } 

字典树可用于计算某个文本中出现次数最多的前k个单词:遍历文本中的单词,将每个单词插入到字典树中,重复的单词实际不再添加,而是将原有单词末尾节点中的count加1,最后,字典树中根节点到所有endFlag为true的节点的路径为文本中出现的所有单词,节点中的count值为这些单词出现的次数,通过排序可以得到出现次数最多的前k个单词。