当前位置:   article > 正文

字典树 Trie

字典树 Trie

概念

字典树,它跟我们查字典的步骤类似,打个比方,我们在查字典的时候会首先查第一个字母,然后在继续寻找第二个字母,以此类推直到找到对应的单词。

这个过程和用于字符匹配的字典树一样,假如我们在字典树第二层已经找不到第一个字母了(第一层为Root, 不用于表示字符),那么表示这个单词根本不存在字典树里;假设第一个字母找到了,那么继续在下一层寻找下一个字符,依次往下层匹配字符,直到匹配到叶子节点或者不存在。它是树形结构,如下图所示:

这里写图片描述

核心思想

以空间换时间,利用字符串的公共前缀来降低时间开销,最大限度的减少无谓的字符串比较。

字典树不仅可以用来存储字符,也可以用来存储数字。

基本性质

  • 根节点不包含字符,除根节点以外的每个节点只表示一个字符。
  • 从根节点到某一节点,此路径上经过的节点连接起来,为该节点对应的字符串。
  • 每个节点的所有子节点表示的字符串都不相同。

应用

先给出字典表,然后在给出单词,查找单词是否在字典中。
刚好碰到一个题目,要求执行上面的操作。先输入5个单词存为字典,然后查找下面的2个单词是否在字典表中,存在输出 yes, 否则输出 false.

题目input:

5
you
me
love
have
colorful
2
your
colorful

output

false
true

思路

  • 先建立5个单词的字典树
  • 在字典树查找单词,通过判定节点是否存在,是否为叶子节点来确定。

源码

#include <stdio.h>
const int SIZE = 26; //26个字母

//字典树结构体
typedef struct Node_
{
 bool isLeaf;        //是否为叶子节点
 Node_ *child[SIZE]; //每个字符的表示
}Node;

Node tree[10000];

//获取字符串长度
int getLen(char *s)
{
   int ret = 0;
   while(s[ret]) ret++;
   return ret;
}

//初始化tree数组,每个孩子都为空,表示当前还是空树
void init()
{
  for(int i = 0; i < 10000; i++)
  {
     for(int j = 0; j < SIZE; j++)
     {
         tree[i].isLeaf = false;
         tree[i].child[j] = NULL;
     }
  }
}

int main()
{
 init();

 int num;
 scanf("%d", &num);

 int cnt = 0;
 Node *root = &tree[cnt++]; //根节点不表示字符

 char c[21];

 for(int i = 0; i < num; i++)
 {
     scanf("%s", c);
     int len = getLen(c);

     //建立字典树
     Node* p = root;
     for(int j = 0; j < len; j++)
     {
         int index = c[j] - 'a';         //表示对应的字符
         if(p->child[index] == NULL)
             p->child[index] = &tree[cnt++]; //为字符分配地址
         p = p->child[index];
     }
     p->isLeaf = true;//当前节点为根节点,用于判断是否存在于字典树中
 }

 int T;
 scanf("%d", &T);

 for(int i = 0; i < T; i++)
 {
     scanf("%s", c);
     int len = getLen(c);

     int count = 0;
     int index;

     //查询字典树
     Node* p = root;
     while(p && count < len)
     {
         index = c[count] - 'a';//对应字符
         p = p->child[index];//对应的字符有分配地址,表示匹配到
         count++;
     }


     if(p && p->isLeaf)//节点存在并且为叶子节点,说明在字典树中存在这个单词
         printf("#%d true", i+1);
     else
         printf("#%d false", i+1);

     printf("\n");
 }
 return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92

参考

维基百科 Trie

本文原创首发于微信公众号 [ 林里少年 ],欢迎关注第一时间获取更新。

这里写图片描述

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号