标签:字典树 trie
Trie,又称字典树,前缀树(prefix tree),是一种树形结构,用于保存大量的字符串。
它的优点是:利用字符串的公共前缀来节约存储空间。查找、插入复杂度为O(n),n为字符串长度。
它有3个基本性质:
1. 根节点不包含字符,除根节点外每一个节点都只包含一个字符。
2. 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。
3. 每个节点的所有子节点包含的字符都不相同。
假设有abc,abcd,abd, b, bcd,efg,hii这7个单词,可构建字典树如下:

查找一个字符串时,我们只需从根结点按字符串中字符出现顺序依次往下走。如果到最后字符串结束时,对应的结点标记为红色,则该字符串存在;否则不存在。
插入时也只需从根结点往下遍历,碰到已存在的字符结点就往下遍历,否则,建立新结点;最后标记最后一个字符的结点为红色即可。
实现代码:
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#define MAX 26
using namespace std;
typedef struct TrieNode
{
int count;
struct TrieNode *next[MAX];
}TrieNode;
void InitTrie(TrieNode **root)
{
*root=NULL;
}
TrieNode* CreateNode()
{
int i;
TrieNode *p;
p=(TrieNode *)malloc(sizeof(TrieNode));
if(!p)
{
printf("No enough memory!\n");
exit(-1);
}
p->count=1;
for(i=0;i<MAX;i++)
p->next[i]=NULL;
return p;
}
void InsertTrie(TrieNode **root,char *str)
{
int i=0,k=0;
TrieNode *p=*root;
if(p==NULL)
{
p=*root=CreateNode();
}
for(i=0;str[i]!='\0';i++)
{
k=str[i]-'a';// 假设全部为小写字母
if(p->next[k])
p->next[k]->count++;
else
p->next[k]=CreateNode();
p=p->next[k];
}
}
bool Search(TrieNode **root,char *str)
{
int i,k;
TrieNode *p=*root;
for(i=0;str[i]!='\0';i++)
{
k=str[i]-'a';
if(p->next[k]==NULL)
return false;
else
p=p->next[k];
}
return true;
}
int main(int argc,char *argv[])
{
int n;
char str[MAX];
TrieNode *root;
InitTrie(&root);
scanf("%d",&n);
getchar();
for(int i=0;i<n;i++)
{
scanf("%s",str);
InsertTrie(&root,str);
}
printf("Please input the string you want to search:\n");
scanf("%s",str);
if(Search(&root,str))
printf("Find it\n");
else
printf("Can Not Find it\n");
return 0;
}
标签:字典树 trie
原文地址:http://blog.csdn.net/cstopcoder/article/details/26620707