字典树
在我们的网络生活中,处处都有热搜的身影,这天某某某递出了律师函,那天某站又泄露了源码,等等
那么,这个热搜是怎么实现的呢?
一种办法,我可以用一种数组,下标是关键词,然后键值是被搜索的次数,然后每次被检索后都进行一次排序,emmm,这种办法虽然简单,但是时间复杂度和空间复杂度都很大,如果应用到现实生活中,没有什么效率,
那么我们有更好的办法吗?当然是有的,在网上找的资料上,可以用很多中方法实现,这里的话,我给大家介绍一种数据结构,叫字典树,也可以实现热搜功能
那么,什么是字典树呢?
字典树,顾名思义,它肯定有字典的功能。回顾一下我们查字典的过程(查英文单词),先找第一个字母,再找第二个字母,再找第三个字母…通常我们找到倒数第二个字母就可以找到这个单词在多少页了
这里的话,我们假设我们的字典里面的单词只有b,abc,abd,bcd,abcd,efg,hii 这六个单词
我们就可以按照字典那样把他们建成一颗树
看到这课树,是不是感觉清晰了很多呢?
如果我们要查abcd 这个关键词出现了多少次,那么我们就沿着第一条分支来走一次,走到d那个位置的时候,进行查询就可以。
如何构造一颗字典树
了解完字典树是什么之后,我们再来看看怎么构建吧,(下面的代码都是c++语言的)
//字典树所需要的数据结构
const int maxn=27;
struct node {
int number=0;//代表以当前字母为结尾的单词在树里面出现了多少次
int flag//标记,看是不是最后一个字母
struct *node next[maxn];
};
void creat()
{
node *root=new node();
root->flag=0;
root->number=0;
memset(root->next,NULL,sizeof(root->next));
}
//插入一个单词到字典树里面
void insert(node *root,char *word)
{
node *location=root;
while(*word)
{
if(location->next[*word-'a']==NULL)
{
node *tmp=new node();
tmp->flag=0;
memset(tmp->next,NULL,sizeof(tmp->next));
location->next[*word-'a']=tmp;
}
location=location->next[*word-'a'];
location->number++;
word++;
}
location->flag=1;
}
```
查询关键词出现的次数
```cpp
int search(node *root,char *word)
{
node *location = root;
while(*word&&location)
{
location = location->next[*word-'a'];
word++;
}
if(location&&location->flag){
return location->number;
}
else {
cout<<"error\n";
return 0;
}
}
void Delete(node *root);
{
for(int i=0;i<26;i++)
{
if(root->next[i])
{
Delete(root->next[i]);
}
}
delete root;
}
通过上面的操作,我们大概对实现热搜有了一个大概的思路了,当然,热搜功能不仅仅是只用字典树能够完成的,还需要堆来实现排序呢功能,有兴趣的可以自己下来找一下资料。
一点扩展
不知道大家发现没有,字典树的功能不仅仅是用于统计关键词出现的次数,它还可以做关键词联想
就像这样,具体原理也很简单,读者自己可以想想。