0x16
Trie
Trie
(字典树)是一种用于字符串快速检索的多叉树结构。Trie
的每个节点都拥有若干字符指针,若在插入或检索时扫描到一个字符c,就沿着当前节点的c字符指针,走向该指针指向的节点。下面我们详细讨论Trie
的基本操作过程。
初始化:
一棵空Trie
仅包含一个根节点,该点的字符指针均指向空。
插入:
当需要插入一个字符串 S S S时,我们令一个指针 P P P起初指向根节点。然后依次扫描 S S S中的每个字符c。
1.若 P P P的c字符指针指向一个已经存在的节点 Q Q Q,则令 P = Q P=Q P=Q。
2.若 P P P的c字符指针指向空,则新建一个节点 Q Q Q,令c的字符指针指向 Q Q Q,然后令 P = Q P=Q P=Q。
当 S S S中的字符扫描完毕时,在当前节点的 P P P上标记它是一个字符串的结尾。
检索:
当需要检索一个字符串 S S S是否存在于字典树中,我们令一个指针 P P P起初指向根节点,然后依次扫描 S S S中的每个字符c。
1.若
P
P
P的c字符指针指向空,则说明
S
S
S没有被插入Trie
,结束检索。
2.若 P P P的c字符指针指向一个已经存在的节点 Q Q Q,则令 P = Q P=Q P=Q。
当
S
S
S中的字符扫描完毕时,若当前结尾被标记成一个字符串的结尾,则说明
S
S
S存在于Trie
中,否则,则说明
S
S
S没有被插入Trie
。
int trie[SIZE][26]; //这里的SIZE是总的字符数,假设字符串全为小写字母组成
//trie[i][2]=j代表序号为i的字符与c字符有连接,并且c字符的序号为j
bool end[SIZE];
int tot=0;
void insert(string s)
{
int p=0;
for(int i=0;i<s.size();++i)
{
int ch=s[i]-'a';
if(trie[p][ch]==0)
trie[p][ch]=++tot;
p=trie[p][ch];
}
end[p]=true; //如果有重复字符串,end可以定义为int end[SIZE],然后记录重复个数
}
bool search(string s)
{
int p=0;
for(int i=0;i<s.size();++i)
{
int ch=s[i]-'a';
if(trie[p][ch]==0)
return false;
p=trie[p][ch];
}
return end[p];
}