Trie 字典树
字典树是哈希树的变种, 它采用公用前缀的方式来提高效率, 刚开始以为公用前缀, 空间会节省, 后来想想, 空间也不是节省, 因为每一个都有26个指针(这里假设都是小写字母的话), 不过他的时间复杂度是常数级的, 效率非常高, O(1)的复杂度, 它是典型的空间换时间, 他常用的功能是增删查, 其实删除并不算太常用, 增加和查找用的比较多点.具体的实现代码如下:
1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 //结构体里面可以灵活的加一些东西,根据功能来加 5 typedef struct Node{ 6 int isWord;//标记是否到这里是个单词 7 struct Node *next[26];//26个子孩子, 8 }Node, *PNode; 9 10 void add_word(PNode *root, char *word)//将指定单词添加到字典树 11 { 12 PNode node; 13 int len = strlen(word); 14 int i = 0; 15 PNode ptr = *root; 16 while(i < len) 17 { 18 if(ptr->next[word[i] - 'a'] == NULL) 19 { 20 node = (PNode)malloc(sizeof(Node)); 21 for(int j = 0; j < 26; j++) 22 { 23 node->isWord = 0; 24 node->next[j] = NULL; 25 } 26 ptr->next[word[i] - 'a'] = node; 27 } 28 ptr = ptr->next[word[i] - 'a']; 29 i++; 30 } 31 ptr->isWord = 1;//最后标记这个点是单词的结尾 32 } 33 34 void search_word(PNode root, char *word)//查找单词,递归方式 35 { 36 if(word[0] != '\0' && root->next[word[0] - 'a'] == NULL) 37 { 38 printf("No this word\n"); 39 return; 40 } 41 if(word[0] == '\0') 42 { 43 if(root == NULL) 44 printf("exist!\n"); 45 else 46 { 47 if(root->isWord == 1) 48 printf("exist!\n"); 49 else 50 printf("No this word\n"); 51 } 52 return; 53 } 54 search_word(root->next[word[0] - 'a'], word + 1); 55 } 56 //查找单词,非递归方式 57 int search_words(PNode root, char *word) 58 { 59 int len = strlen(word); 60 int i = 0; 61 PNode ptr = root; 62 while(i < len) 63 { 64 if(ptr->next[word[i] - 'a'] == NULL) 65 return 0; 66 ptr = ptr->next[word[i] - 'a']; 67 i++; 68 } 69 if(ptr->isWord == 1) 70 return 1; 71 return 0; 72 } 73 //删除指定的单词,这里只是将它的标记设为0, 并没有真正意义上的删除 74 void delete_word(PNode *root, char *word) 75 { 76 if(word[0] == '\0' && (*root) != NULL) 77 { 78 (*root)->isWord = 0; 79 return; 80 } 81 if((*root) == NULL) 82 { 83 printf("No this word\n"); 84 return; 85 } 86 delete_word(&(*root)->next[word[0] - 'a'], word + 1); 87 } 88 //删除整个字典树,真正的删除 89 //如果要在函数里面调用此函数的时候,调用完之后如果还想创建树,要重新malloc根节点 90 void delete_all(PNode root) 91 { 92 for(int i = 0; i < 26; i++) 93 { 94 if(root->next[i] != NULL) 95 delete_all(root->next[i]); 96 } 97 free(root); 98 } 99 100 int main() 101 { 102 int choice; 103 char str[100]; 104 PNode root = (PNode)malloc(sizeof(Node)); 105 root->isWord = 0; 106 for(int i = 0; i < 26; i++) 107 root->next[i] = NULL; 108 do{ 109 //测试菜单 110 printf("1. add word 2. search word 3. delete word 0. exit\n"); 111 scanf("%d", &choice); 112 switch(choice) 113 { 114 case 1: 115 scanf("%s", str); 116 add_word(&root, str); 117 break; 118 case 2: 119 scanf("%s", str); 120 if(search_words(root, str) == 1) 121 printf("exist\n"); 122 else 123 printf("not found\n"); 124 //当然也可以用递归的那个 125 // search_word(root, str); 126 break; 127 case 3: 128 scanf("%s", str); 129 delete_word(&root, str); 130 default: 131 break; 132 } 133 }while(choice != 0); 134 delete_all(root); 135 return 0; 136 }