字典树 Trie

原理

字典树又称前缀树,当我们要存储多个字符串时,若每段字符串单独存储,则查找以及空间效率都很低。
有一些字符串是另一些的前缀,或者两个字符串的前缀有重合,利用这一性质,我们建一个字典树,又叫前缀树,前缀相同的字符串前缀相同部分都只会被存储一次

例子

字典树
有字符串 a,ab ,acd,bc;

  1. 对于每个插入的字符串,首先从根节点出发,查找是否有匹配的子节点 如插入 "ab"时,首先在 root节点查找是否有 值为’a’的子节点,若没有,则直接插入。
  2. 再对该节点进行如第一步操作,继续查找是否有下一字符的节点。
  3. 若到达字符串尾部,则结束,标记该点。

结论

1.从根节点到任意被标记的节点,都是一个字符串。
2.有相同前缀的两个字符串,它们在树中一部分重复。

具体实现

虽然是树,但是一般不用指针实现,因为指针操作太繁琐
这里用的是数组实现,而每个节点存的就是它不是子节点的指针,而是下标 。
下面是节点结构:

struct tree{
	int vis[26];//存子节点下标
	int end;//判断是否是字符串
}ac[10000005];
  • vis数组存储子节点下标,这个字典树处理的是英语字母上的字符串,字符集有26个元素,因此最多有26个子节点。
  • end用来判断从根节点到该节点是否构成一个字符串。

构造:

int cnt;//trie树中结点个数
void build(int n){
	int i,j,k,l,now;
	for(i=0;i<n;i++){
		scanf("%s",s);
		l=strlen(s),now=0;//默认根节点下标为0
		for(j=0;j<l;j++){
			if(ac[now].vis[s[j]-'a']==0)//不存在
			ac[now].vis[s[j]-'a']=++cnt;//插入结点
			now=ac[now].vis[s[j]-'a'];//更新当前结点
		}
		ac[now].end+=1;//数目加一
	}
}
  • cnt存储的是结点个数
  • vis子节点不存在默认初始化为0
  • now存储当前结点

到了这里 一个trie树就建成了,至于具体应用?等我的ac自动机吧。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值