题目链接:http://acm.nbut.cn/Problem/view.xhtml?id=1393
Trie树也叫字典树,是一种用于快速检索的多叉树结构。如英文字母的字典树是一个26叉树。数字的字典树是一个10叉树。Trie树把要查找的关键词看作一个字符序列,并根据构成关键词字符的先后顺序构造用于检索的树结构;一棵m度的Trie树或者为空,或者由m棵m度的Trie树构成。特别的:和二叉查找树不同,在Trie树中,每个结点上并非存储一个元素。在Trie树中查找一个关键字的时间和树中包含的结点数无关,而取决于组成关键字的字符数。
特点:
①利用串的公共前缀->节约内存。
②根结点(root)不包含任何字母。
③其余结点仅包含一个字母(非元素)。
④每个结点的子结点包含字母不同。
查找过程:
①在Trie树上进行检索总是始于根结点。
②取得要查找关键词的第一个字母,并根据该字母选择对应的子树并转到该子树继续进行检索。
③在相应的子树上,取得要查找关键词的第二个字母,并进一步选择对应的子树进行检索。
④在某个结点处,关键词的所有字母已被取出,则读取附在该结点上的信息,即完成查找。
字典树比较一般的实现是用指针,所以又可分为动态开辟内存的字典树和静态开辟内存的字典树。两种写法各有长处,一般静态的速度较快,而动态的代码较简。
3
ab abc a
3 a ab abc
struct Node
{
int sum;//记录多少单词拥有以该节点为末尾的前缀
Node *lt[26];//后续节点, 其中26是表示每层有多少种类的数,可根据题意自行更改
}a[500100];//开辟静态内存Node *head;//头节点
3.查询操作void insert(char str[]) //插入的字符串下标。。
{
int i,j;
Node *t,*s=head; //将s指向头节点
int len=strlen(str); //计算插入字符串的长度
for (i=0;i<len;i++)
{
int id=str[i]-'a'; //将字符转换成0-26的形式给id,如'a'-'a'=0
if (s->lt[id]==NULL) //如果s的相应子节点为空,则从s的br[id]节点建树
{
t=&a[time++]; //使用已开辟的静态,并将指向静态内存的指针往下移
for (j=0;j<26;j++)
{
t->lt[j]=NULL;
}
t->sum=0;
s->lt[id]=t;
}
s=s->lt[id];
s->sum++;
}
}
int query(char str[])
{
int i,sum=0;
Node *s=head;
int len=strlen(str);
for (i=0;i<len;i++)
{
int id=str[i]-'a';
if (s->lt[id]==NULL) //如果查询的字符不存在,直接返回0
{
return 0;
}
else
{
s=s->lt[id]; //将指针指向下一个字符
sum=s->sum; //改变sum的值
}
}
return sum;
}
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct Node
{
int sum;
Node *lt[26];
}a[500100];
Node *head;
int time=0;
void insert(char str[])
{
int i,j;
Node *t,*s=head;
int len=strlen(str);
for (i=0;i<len;i++)
{
int id=str[i]-'a';
if (s->lt[id]==NULL)
{
t=&a[time++];
for (j=0;j<26;j++)
{
t->lt[j]=NULL;
}
t->sum=0;
s->lt[id]=t;
}
s=s->lt[id];
s->sum++;
}
}
int query(char str[])
{
int i,sum=0;
Node *s=head;
int len=strlen(str);
for (i=0;i<len;i++)
{
int id=str[i]-'a';
if (s->lt[id]==NULL)
{
return 0;
}
else
{
s=s->lt[id];
sum=s->sum;
}
}
return sum;
}
int main()
{
int n,m,i;
while (~scanf("%d",&n))
{
time=0;
head=&a[time++];
for (i=0;i<26;i++)
{
head->lt[i]=NULL;
head->sum=0;
}
char str[20];
getchar();
for (i=0;i<n;i++)
{
scanf("%s",str);
insert(str);
}
scanf("%d",&m);
getchar();
for (i=0;i<m;i++)
{
scanf("%s",str);
printf("%d\n",query(str));
}
}
return 0;
}