一. 为什么要使用Trie树
Trie树可以将大量字符串通过树形结构组织起来,前缀相同的字符串共享存储空间,从而达到1)节约存储空间,2)加快特定查找速度(例如,以给定字符串开头的字符串的个数等)。
二. C实现Trie树
Trie树的建立
void create_tree(struct Node* T, char dir[]){
int jc=1; //root节点已经在main函数中create,故从第二个字符串开始建树
T->num_word++;
struct Node* temp = T;
while(dir[jc] != '\0'){
int flag = 0; //用来监控当前字符是否存在于树中
int it=0;
for(; it<temp->num_child; it++){
if(dir[jc] == temp->child[it]->data){
temp = temp->child[it];
temp->num_word++;
flag = 1; //当前字符存在
break;
}
}
if(flag == 0){ //当前字符不存在
struct Node* Tc = (struct Node*)malloc(sizeof(struct Node));
Tc->num_word = 1;
Tc->data = dir[jc];
Tc->num_child = 0;
temp->child[temp->num_child] = Tc;
temp->num_child++;
temp = Tc;
}
jc++;
}
}
Trie树的搜索
void compare(struct Node* T, char dir[]){
int jc=1, result = 0;
struct Node* temp = T;
int flag = 0;
while(dir[jc] != '\0'){
int it=0;
flag = 0;
for(; it<temp->num_child; it++){
if(dir[jc] == temp->child[it]->data){
temp = temp->child[it];
flag = 1;
break;
}
}
if(flag == 0)
break;
jc++;
}
if(dir[jc] == '\0')
result = temp->num_word;
else
result = 0;
printf("%d\n", result);
}
主函数部分
int main(void){
int sum_line = 0, sum_compare = 0, i=0, index=0;
char dir[11];
struct Node table[27];
memset(table, '\0', sizeof(table));
scanf("%d", &sum_line);
for(; i<sum_line; i++){
memset(dir, '\0', 11);
scanf("%s", dir);
index = (int)dir[0] -97;
table[index].data = dir[0];
create_tree(&table[index], dir);
}
scanf("%d", &sum_compare);
for(i=0; i<sum_compare; i++){
memset(dir, '\0', 11);
scanf("%s", dir);
index = (int)dir[0] - 97;
compare(&table[index], dir);
}
return 0;
}
三. 思考
(以上实现当然有更优的方式。)这里我们主要看重的是,1)Trie树的思想;2)Trie的建立和搜索方式。