版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/decision2016/article/details/54646396
Trie树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。
上面是百度百科找的,trie树=字典树=前缀树,下面就说说前缀树的实现。
首先trie树的根必定是一个空节点,每一条边代表了一个字符,每一个节点有多种可能,那么我们可以使用一个数组来达到这个目的;
同时,每一个单词(字符串)的最后一个字符所指向的节点需要做标记(如上图的红色节点),以表示从树根到现在所遍历的一个字符串;
那么上面所说的就可以通过一个结构体来实现。
int num = 26; //以26个小写字母为例
struct TrieNode
{
bool isTri;
TrieNode *next[num];
};
然后这个trie就需要插入字符串,删除节点,以及查找字符串,当然,插入字符串的函数或者搜索字符串也可以用来删除某一字符串;插入字符串,从根节点开始,依次遍历字符串中的每一个字符,同时也建立新的节点,以达到插入的目的,下面是代码的实现:
void Insert(TrieNode* root,const char* word)
{
TrieNode *now = root;
while(*word)
{
if(now->next[*word-'a']==NULL) //*word-'a'用于表示某一字符的位置
{
TrieNode *newNode = new TrieNode();
newNode->isTri = false;
newNode->yes = 0;
memset(newNode->next,NULL,sizeof(newNode->next));
now->next[*word-'a'] = newNode;
}
now = now->next[*word-'a'];
word++;
}
now->isTri = true;
}
搜索字符串,也是从根节点开始,依次遍历,直到树的最深处或者到达字符串的最后一个字符为止,在这个时候就可以如果到达数的最深处的时候字符串仍然没有遍历完,或者遍历完最后一个字符的时候这个加点未被标记,那么我们就可以返回false的信息,表示没有搜索到;反之,如果遍历字符串结束之后并且此时的节点被标记(存储过该字符串),则返回true的信息,当然搜索这里还有部分的应用,这里就不说了。
扫描二维码关注公众号,回复:
3962080 查看本文章
bool Search(TrieNode* root,const char* word)
{
TrieNode *now = root;
while(*word)
{
if(*word&&now != NULL)
{
now = now->next[word-'a'];
word++;
}
}
return (now->isTri&&now!=NULL);
}
删除节点,就是使用递归的方式删除节点,从某一节点开始,依次遍历其所有节点,又继续删除;
void Delete(TrieNode* node)
{
for(int i = 0;i<num;i++)
{
if(node->next[i]!=NULL)
{
Delete(node->next[i]);
}
}
delete node;
}
完整代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int num = 26;
struct TrieNode
{
bool isTri;
TrieNode *next[num];
}
void Insert(TrieNode* root,const char* word)
{
TrieNode *now = root;
while(*word)
{
if(now->next[word-'a']==NULL)
{
TrieNode *newNode = new TrieNode();
newNode->isTri = false;
memset(newNode->next,NULL,memset(newNode->next));
now->next[word-'0'] = newNode;
}
now = *newNode;
word++;
}
now->isTri = true;
}
bool Search(TrieNode* root,const char* word)
{
TrieNode *now = root;
while(*word)
{
if(*word&&now != NULL)
{
now = now->next[word-'a'];
word++;
}
}
return (now->isTri&&now!=NULL);
}
void Delete(TrieNode* node)
{
for(int i = 0;i<num;i++)
{
if(node->next[i]!=NULL)
{
Delete(node->next[i]);
}
}
delete node;
}
int main()
{
TrieNode *root = new TrieNode();
root->isTri = false;
memset(root->next,NULL,sizeof(root->next));
//主函数就不写了,这里就是应用数据结构的地方,交代一下根节点的初始化即可
return 0;
}