Trie树模版

Trie 树 中文名叫字典树,可以用来存放n个单词,并且找出某个前缀的数量,或者找出某个单词的数量。

其实也有其他的应用,比如统计有多少个不同的字符串等等。

字典树分为一般分为两个部分,一个是创建字典树,还一个是find函数,find函数的写法随着题目要求可以灵活多变的!

首先 要先定义出数据结构 。
1  struct Trie{
2 Trie *next[26]; //指向子节点
3 int v; //可以很多个变量,比如可以统计这个前缀的数量,或者标记是不是结尾等等
4 };
5 Trie *root;
View Code

 


初始化函数:
1 void init()
2 {
3 root = (Trie*)malloc(sizeof(Trie));
4 for(int i = 0;i < 26;i++)
5 root->next[i] = NULL;
6 }
View Code

 


创建字典树:

 1 void creat_Trie(char *str)  //创建字典树 
 2 { 
 3     int len = strlen(str);  //字符串的长度 
 4     Trie *p = root, *q;// p 指向字典树,定义一个指针q 
 5     for(int i=0; i<len; ++i)//遍历整个字符串 
 6     {
 7         int id = str[i]-'0';  //得到每个字符的值 
 8         if(p->next[id] == NULL)//如果该值在字典树中是第一次出现 
 9         {
10             q = (Trie *)malloc(sizeof(Trie));//开辟一个新节点 
11             q->v = 1;    //初始v==1,遇到一个新节点,则把经过这个节点的字符串数量初始化为1 
12             for(int j=0; j<MAX; ++j)//让其的每种可能的下一个节点都为空 
13                 q->next[j] = NULL;
14             p->next[id] = q;//让p指向过去  
15             p = p->next[id];//p指向开节点的后一节点 
16         }
17         else
18         {
19             p->next[id]->v++;//如果存在,则让v++ , 意思是通过这个节点的字符串数量又多了一个 
20             p = p->next[id];//下一个节点。。 
21         }
22     }
23      // p->t = -1;   //若为结尾,则将v改成-1表示(视情况而定)
24 }
View Code

 

 
 find函数:
 
 1 int findTrie(char *str)
 2 {
 3 int len = strlen(str);   //查找这个串是否在字典树中 
 4 Trie *p = root;//让p 指向字典树的一个节点。 
 5 for(int i=0; i<len; ++i)
 6 {
 7 int id = str[i]-'0';  //根据需要选择是减去'0'还是'a',或者是'A'
 8 p = p->next[id]; //注意,如果这里指向下一届点了,下面判断就只能是p == NULL  如果要是p->next[id] == NULL 就应该在循环末尾进行。
 9 if(p == NULL)   //若为空集,表示不存以此为前缀的串
10 return 0;
11 if(p->v == -1)   //字符集中已有串是此串的前缀
12 return -1;
13 }
14 return -1;   //此串是字符集中某串的前缀
15 } 
View Code

 


注意指针的 难调试性,写的时候千万不能写错了。。。
 
llj:
 1 /*
 2 ch[i][j]表示: i结点的j编号,如果该值为0,则没有j编号这个结点,比如 i = 1(即该字符为b),j=2(字符对应c),则 ch[i][j]:在b字母下面没有c,即还没有含有bc的字符串。 
 3 */
 4 struct Trie
 5 {
 6     int ch[maxnode][sigma_size];
 7     int val[maxnode];
 8     int sz;
 9     Trie() : sz(1) { memset(ch[0], 0, sizeof(ch[0])); }
10     void reset() { memset(ch, 0, sizeof(ch)); memset(val, 0, sizeof(val)); sz = 1; }
11     int idx(char c) { return c - 'a'; }
12 
13     void insert(char * s, int v)
14     {
15         int u = 0;
16         for(int i = 0; s[i]; ++i)
17         {
18             int c = idx(s[i]);
19             if(!ch[u][c])
20             {
21                 memset(ch[sz], 0, sizeof(ch[sz]));
22                 val[sz] = 0;
23                 ch[u][c] = sz++;
24             }
25             u = ch[u][c];
26         }
27         val[u] = v;
28     }
29 
30     int query(char * s, int a) 
31     {
32         int u = 0, res = 0;
33         for(int i = a; s[i]; ++i)
34         {
35             int c = idx(s[i]);
36             if(!ch[u][c]) return res;
37             u = ch[u][c];
38             if(val[u])  // 查询到单词节点
39             {
40 41             }
42         }
43         return res;
44     }
45 }T;
View Code

 

 

 

posted on 2015-07-17 09:16  小松song  阅读(136)  评论(0)    收藏  举报

导航