Trie 树 中文名叫字典树,可以用来存放n个单词,并且找出某个前缀的数量,或者找出某个单词的数量。
其实也有其他的应用,比如统计有多少个不同的字符串等等。
字典树分为一般分为两个部分,一个是创建字典树,还一个是find函数,find函数的写法随着题目要求可以灵活多变的!
首先 要先定义出数据结构 。
1 struct Trie{ 2 Trie *next[26]; //指向子节点 3 int v; //可以很多个变量,比如可以统计这个前缀的数量,或者标记是不是结尾等等 4 }; 5 Trie *root;
初始化函数:
1 void init() 2 { 3 root = (Trie*)malloc(sizeof(Trie)); 4 for(int i = 0;i < 26;i++) 5 root->next[i] = NULL; 6 }
创建字典树:
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 }
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 }
注意指针的 难调试性,写的时候千万不能写错了。。。
时间: 2024-10-14 05:46:36