trie树,又称字典树、前缀树,是一个用于快速检索字符串或数字串的多叉树。它话费较大的存储空间(O(26^n))来获得线性时间的检索效率,其中n是输入的字符串的长度。
我们使用动态数据结构来存储之。下面是一个字符串的trie树。
#include <stdio.h>
#include <stdlib.h>
#define N 26
typedef struct _trie_node{
int end; /* 字符串结束标志,0表示没有结束,非0表示已经结束 */
char ch; /* 该节点的字符,用ASCII码的0表示根节点,根节点的值无意义 */
struct _trie_node * child[N]; /* N个孩子节点 */
} * ptr_trie_node, * trie;
ptr_trie_node create_trie_node (char c){
ptr_trie_node nd = (ptr_trie_node) malloc (sizeof (struct _trie_node));
int i;
nd->end = 0;
nd->ch = c;
for (i=0; i<N; i++){
nd->child[i] = NULL;
}
return nd;
}
trie trie_init (trie * ptr_tree, char c){
return (* ptr_tree) = create_trie_node (c);
}
int stringlen ( const char str[]){
char * p = str;
int len = 0;
while (* p){
p ++;
len ++;
}
return len;
}
trie trie_insert (trie * ptr_tree, const char str[]){
int i = 0;
int len = stringlen (str);
trie tree = * ptr_tree;
for (i = 0; i<len; i++){
if (! tree->child[str[i] - 'a']){
tree->child[str[i] - 'a'] = create_trie_node (str[i]);
}
tree = tree->child[str[i] - 'a'];
}
tree->end = 1;
return tree;
}
int trie_find (trie tree, const char str[]){
int i = 0;
int len = stringlen (str);
while (i < len){
if (! tree->child[str[i] - 'a']){
break;
}
tree = tree->child[str[i] - 'a'];
i ++;
}
return (i == len && ! (0 == tree->end)) ? 1 : 0;
}
void trie_destroy (trie tree){
int i = 0;
for (i = 0 ; i < N; i ++){
if (tree->child[i]){
trie_destroy (tree->child[i]);
}
}
free (tree);
tree = NULL;
}
int main (int argc, char * agrv[] ){
trie tree;
int i;
trie_init (&tree, 0);
trie_insert (&tree, "abcd");
trie_insert (&tree, "bcad");
i = trie_find (tree, "abcd");
printf ("%d\n", i);
i = trie_find (tree, "bcad");
printf ("%d\n", i);
i = trie_find (tree, "bd");
printf ("%d\n", i);
trie_destroy (tree);
return 0;
}
结果是
1
1
0