trie树,即字典树,是一种基于多字符串匹配的数据结构,该结构由根开始向下走到底,其中由跟到叶节点的一条路径组成了一个字符串。
其匹配的是到目标字符ch2位置,从ch2之前的某个字符ch1开始ch1....ch2为一种目标字符串。
//主要代码包含4部分,trie node部分 初始化和删除部分 插入 寻找
struct Node
{
char* val;
Node *next[26];
Node()
{
for(int i=0;i<26;i++)
next[i]=NULL;
val=NULL;
}
};
struct Trie
{
Node *root;
Trie(){root=newNode();}
void init(){del(root);root = newNode();}
Node *newNode(){return new Node;} //初始化结点
inline int idx(char c){return c - 'a';}
void insert(char *s, char *v)
{
Node *u=root;
int len=strlen(s);
for(int i=0;i<len;i++)
{
int c=idx(s[i]);
if(u->next[c]==NULL)
u->next[c]=newNode();
u=u->next[c];
} //构建到最后进行赋值
u->val=new char[11];
strcpy(u->val,v);
}
void find(char *s)
{
Node *u=root;
int len=strlen(s);
for(int i=0;i<len;i++)
{
int c=idx(s[i]);
if(u->next[c]==NULL)
{
printf("%s", s);
return;
}
u=u->next[c];
}
if(u->val)
printf("%s",u->val);
else
printf("%s",s);
}
void del(Node *rt) //dfs递归删除结点
{
if(rt==NULL)
return;
for(int i=0;i<26;i++)
if(rt->next[i])
del(rt->next[i]);
delete rt->val;
delete rt;
}
};
Trie trie;
数组优化
struct node
{
bool exist;
int next[12];
node()
{
exist=0;
memset(next,0,sizeof(next));
}
};
struct Trie
{
int tot;
node trie[100005];
Trie(){tot=1;memset(trie,0,sizeof(trie));}
void init(){tot=1;memset(trie,0,sizeof(trie));}
inline int idx(char c){return c-'0';}
bool insert(char *s) //插入字符串建树
{
int u=1;
int len=strlen(s);
for(int i=0;i<len;i++)
{
int c=idx(s[i]);
if(trie[u].next[c]==0)trie[u].next[c]=++tot;
u=trie[u].next[c];
}
trie[u].exist=true;
}
}trie;
左儿子右兄弟优化
结构体实现
struct node
{
node* child;
node* bro;
char ch;
int val;
node(){child=NULL;bro=NULL;ch=0;val=0;}
};
struct Trie
{
node* root;
Trie(){root=newnode();}
node* newnode(){return new node();}
//void init(){root=newnode();}
void init(){del(root);root=newnode();}
//inline int idx(char c){return c-'a';}
inline int idx(char c){return c;}
void del(node* rt)
{
if(rt==NULL)
return;
del(rt->child);
del(rt->bro);
delete rt;
}
void insert(char *s)
{
int len=strlen(s);
node* u=root;
for(int i=0;i<=len;i++)
{
int c=idx(s[i]);
node* tmp=u;
for(tmp=tmp->child;tmp;tmp=tmp->bro) //遍历右兄弟 寻找目标c
if(tmp->ch==c)
break;
if(tmp==NULL) //如果没找到,则建立一个结点连接到u->child上
{
tmp=newnode();
tmp->bro=u->child;
u->child=tmp;
tmp->ch=c;
}
u=tmp;
}
}
int query(char *s)
{
int len=strlen(s);
node* u=root;
for(int i=0;i<=len;i++)
{
int c=idx(s[i]);
node* tmp=u;
for(tmp=tmp->child;tmp;tmp=tmp->bro) //遍历右兄弟 寻找目标c
if(tmp->ch==c)
break;
if(tmp==NULL) //如果没找到,则建立一个结点连接到u->child上
{
return ;
}
else
{
}
u=tmp;
}
}
};
Trie trie;
数组实现
struct Node
{
int child;
int bro;
char ch;
int val;
Node(){child=bro=-1;ch=0;val=0;}
void init(){child=bro=-1;ch=0;val=0;}
};
struct Trie
{
int sz;
Node node[maxn];
Trie(){sz=1;node[0].init();}
void init(){sz=1;node[0].init();}
//inline int idx(char c){return c-'a';}
inline int idx(char c){return c;}
void insert(char *s)
{
int len=strlen(s);
int u=0;
for(int i=0;i<=len;i++)
{
int c=idx(s[i]);
int tmp=u;
for(tmp=node[u].child;tmp!=-1;tmp=node[tmp].bro)
if(node[tmp].ch==c)
break;
if(tmp==-1)
{
tmp=sz++;
node[tmp].init();
node[tmp].bro=node[u].child;
node[u].child=tmp;
node[tmp].ch=c;
}
u=tmp;
}
}
};
Trie trie;
应用
1.Tire树的遍历