字典上是一种树形结构,是利用字符串的公共前缀来节约存储空间,最大限度减少无谓的字符串比较。
Trie树特点:
- 根节点不包含任何字母,其他每个结点都包含一个字母;
- 每个结点的所有儿子包含的字母各不相同;
- 从根节点到某个结点,路径上的字母依次连接起来所构成的字母序列称为该结点对应的单词;
用给定的单词:i、is、he、her、man、map、she。
一、由这些所构成的字典上如下(插入操作):
根节点不包含任何字母,标记每个单词的最后一个字母,用于查找这个单词;
二、判断map是否在字典树上(查找操作):
沿着m->a->p找到单词map所在位置,单词最后一个字母p在字典树上被标记,说明找到了这个单词;
三、删除字典树上的单词her
沿着h->e->r找到单词her所在位置,将单词最后一个字母r在字典树中的标记清除,就相当于删除了这个单词;
四、判断her是否在字典树上
沿着h->e->r找到单词her所在位置,单词最后一个字母r在字典树上没被标记,说明没找到了这个单词,证明上一步的删除操作有效;
字典树插入、删除、查询等操作模板:
const int MAXN = 26;
struct Node
{
bool flag; //标记
Node *next[MAXN];//子节点
Node() //初始化
{
flag=0;
for(int i=0;i<MAXN;i++)
next[i]=NULL;
}
};
Node *CreateNode()//创建一个结点
{
Node *node=new Node();
return node;
}
Node *Insert(Node *trie,char s[])//插入操作
{
Node *t=trie;
int k=0;
while(s[k])
{
int id=s[k]-'a';
if(!t->next[id])
t->next[id]=CreateNode();
t=t->next[id];
k++;
}
t->flag=true; //将单词最后一个字母标记
return trie;
}
bool Search(Node *trie,char s[])//查找操作
{
Node *t=trie;
int k=0;
while(s[k])
{
int id=s[k]-'a';
if(t->next[id])
t=t->next[id];
else
return false;
k++;
}
if(t->flag) //判断最后一个单词是否有标记
return true;
return false;
}
Node *erase(Node *trie,char s[])//删除操作
{
Node *t=trie;
int k=0;
while(s[k])
{
int id=s[k]-'a';
t=t->next[id];
k++;
}
t->flag=0; //删除单词最后一个字母的标记
return trie;
}
void Del_Trie(Node *trie)//清空字典树
{
if(!trie)
return;
for(int i=0;i<MAXN;i++)
{
if(trie->next[i])
Del_Trie(trie->next[i]);
}
delete trie;
}