1.1 什么是trie树
Trie树,即字典树,又称单词查找树或前缀树,
是一种用于快速检索的多叉树结构。
Trie一词来自retrieve, 发音为 /tri:/ “tree”,也有人读为/trai/ “try”.
优点:最大限度地减少无谓的字符串比较,查询效率比哈希表高。
缺点:内存消耗大。
Trie树的核心思想是空间换时间。利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。
Trie树的3个基本性质:
1). 根节点不包含字符,其它节点都只包含一个字符
2). 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。
3). 每个节点的所有子节点包含的字符都不相同。
根据这些性质,可以设计出trie树的结构类型:
#define MAX_OUT_DEGREE 26
enum TRIE_TYPE {
COMPLETED,
UNCOMPLETED
};
struct Trie_s {
char c; /*单一字符*/
struct Trie_schild[MAX_OUT_DEGREE];/*子节点数组*/
enum TRIE_TYPEtype; /*标识是不是一个节点的结束*/
};
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_OUT_DEGREE 26
enum TRIE_TYPE {
COMPLETED,
UNCOMPLETED
};
struct Trie_s {
char c; /*单一字符*/
struct Trie_s *child[MAX_OUT_DEGREE];/*子节点数组*/
enum TRIE_TYPE type; /*标识是不是一个节点的结束*/
};
typedef struct Trie_s * Trie_t;
Trie_t createNewTrieNode(char ch)
{
Trie_t trie;
unsigned int i;
trie = (Trie_t)malloc(sizeof(struct Trie_s));
if(trie == NULL) {
printf("malloc error in createNewTrieNode\n");
return NULL;
}
trie->c = ch;
trie->type = UNCOMPLETED;
for(i = 0; i < MAX_OUT_DEGREE;i++) {
trie->child[i] = NULL;
}
return trie;
}
Trie_t initialization() {
Trie_t root;
root = createNewTrieNode(' ');
return root;
}
unsigned int chartoindex(unsigned char ch)
{
return ch-'a';
}
void insert(const char string[],unsigned int len,Trie_t root)
{
unsigned int i;
unsigned int index;
Trie_t trie;
if(root == NULL) {
printf("the trie tree is empty\n");
return;
}
trie = root;
/*假设字符串都是从a-z和A-Z的字母*/
for(i = 0; i < len; i++) {
index = chartoindex(string[i]);
if(NULL == trie->child[index]) {
trie->child[index] = createNewTrieNode(string[i]);
}
trie = trie->child[index];
}
trie->type = COMPLETED;
}
Trie_t find(const char string[],unsigned int len,Trie_t root)
{
Trie_t trie;
unsigned int i = 0;
unsigned int index;
if(root == NULL) {
printf("the trie tree is empty\n");
return NULL;
}
trie = root;
while(i < len) {
index = chartoindex(string[i++]);
if(trie->child[index] == NULL) {
return NULL;
}
trie = trie->child[index];
}
if(trie->type == COMPLETED) {
return trie;
}
return NULL;
}
void delete(Trie_t root)
{
unsigned int i;
Trie_t trie;
if(root == NULL)
return;
trie = root;
for(i = 0; i < MAX_OUT_DEGREE;i++) {
if(trie->child[i]) {
delete(trie->child[i]);
}
}
free(trie);
trie = NULL;
}
int main(int argc, char *argv[])
{
Trie_t trie;
trie = initialization();
if(trie == NULL) {
printf("trie is empty in main\n");
return -1;
}
insert("abcd",strlen("abcd"),trie);
insert("cef",strlen("cef"),trie);
insert("higk",strlen("higk"),trie);
if(find("cef",strlen("cef"),trie) != NULL) {
printf("find cef in the trie\n");
}else {
printf("can't find cef in the trie\n");
}
if(find("acef",strlen("acef"),trie) != NULL) {
printf("find acef in the trie\n");
}else {
printf("can't find acef in the trie\n");
}
return 0;
}