字典树(Trie)详解
详解字典树(Trie)
本篇随笔简单讲解一下信息学奥林匹克竞赛中的较为常用的数据结构——字典树。字典树也叫Trie树、前缀树。顾名思义,它是一种针对字符串进行维护的数据结构。并且,它的用途超级广泛。建议大家熟练掌握。
字典树的概念
字典树,顾名思义,是关于“字典”的一棵树。即:它是对于字典的一种存储方式(所以是一种数据结构而不是算法)。这个词典中的每个“单词”就是从根节点出发一直到某一个目标节点的路径,路径中每条边的字母连起来就是一个单词。
上图理解:

(标橙色的节点是“目标节点“,即根节点到这个目标节点的路径上的所有字母构成了一个单词。)
从这张图我们可以看出,字典树就是一棵树(emm...有些废话的嫌疑),只不过,这棵树的每条边上都有一个字母,然后这棵树的一些节点被指定成了标记节点(目标节点)而已。
这就是字典树的概念。结合上面说的概念,上图所示的字典树包括的单词分别为:
a
abc
bac
bbc
ca
字典树的功能
根据字典树的概念,我们可以发现:字典树的本质是把很多字符串拆成单个字符的形式,以树的方式存储起来。所以我们说字典树维护的是”字典“。那么根据这个最基本的性质,我们可以由此延伸出字典树的很多妙用。简单总结起来大体如下:
1、维护字符串集合(即字典)。
2、向字符串集合中插入字符串(即建树)。
3、查询字符串集合中是否有某个字符串(即查询)。
4、统计字符串在集合中出现的个数(即统计)。
5、将字符串集合按字典序排序(即字典序排序)。
6、求集合内两个字符串的LCP(Longest Common Prefix,最长公共前缀)(即求最长公共前缀)。
我们可以发现,以上列举出的功能都是建立在“字符串集合”的基础上的。再一次强调,字典树是“字典”的树,一切功能都是“字典”的功能。这也为我们使用字典树的时候提供了一个准则:看到一大堆字符串同时出现,就往哈希和Trie树那边想一下。
字典树的实现及代码实现
把上面的图搬下来...

字典树的两种基本操作分别是建树和查询。其中建树操作就是把一个新单词插入到字典树里。查询操作就是查询给定单词是否在字典树上。
那我们来想一下。
插入操作
假如这个字典只包括26个英文字母(暂且都定为小写),那么这个树的深度会由具体单词不一样而定。但是它的广度范围是可以提前确定好的。对于每个节点,广度最大为26。(因为每个节点的下一个字母(即后缀点)只可能是26个字母。)那么我们可以用结构体开好这个“虚拟全树”(这个名字是笔者自己起的,请大家好好理解)。然后通过深度迭代向里面尝试加入单词。
我们开一个包含\(26\)个后缀指针的结构体。用变量\(now\)来表示指向当前节点编号的一个指针,用\(tot\)变量表示点的编号。\(end\)数组表示当前单词的“目标节点”即单词结尾的那个节点具体是哪个单词的词尾。
那么代码就长成这样:
struct node
{
int nxt[27];
}trie[maxn];
int insert(char s[],int id)
{
int now=0;
int len=strlen(s);
for(int i=0;i<len;i++)
{
int ch=s[i]-'a'+1;
if(!trie[now].nxt[ch])
{
trie[now].nxt[ch]=tot;
tot++;
}
now=trie[now].nxt[ch];
}
end[now]=id;
}
查询操作
查询操作和刚刚的思路大同小异,因为我们已经有了一个“虚拟全树”,那么我们还是按深度向下迭代,对于需要查询的字符串的当前字符,如果这个对应的字符指针为空,就说明不含这个单词,直接跳出即可。当我们都迭代完成之后,直接返回\(end[now]\)即可。(注意,这里不能直接返回\(1\)或\(true\),假如字典中只保存了一个字符串\(abcdef\),而我们查询的是\(abc\),它可以不被跳出地一直迭代到最后,但是它并不是字典中的单词。即,需要考虑字典中单词子串的情况)。
代码:
bool search(char s[])
{
int len=strlen(s);
int now=0;
for(int i=0;i<len;i++)
{
int ch=s[i]-'a'+1;
if(!trie[now].nxt[ch])
return 0;
}
return end[now];
}
字典树(Trie)详解的更多相关文章
- [POJ] #1002# 487-3279 : 桶排序/字典树(Trie树)/快速排序
一. 题目 487-3279 Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 274040 Accepted: 48891 ...
- 『字典树 trie』
字典树 (trie) 字典树,又名\(trie\)树,是一种用于实现字符串快速检索的树形数据结构.核心思想为利用若干字符串的公共前缀来节约储存空间以及实现快速检索. \(trie\)树可以在\(O(( ...
- 字典树trie学习
字典树trie的思想就是利用节点来记录单词,这样重复的单词可以很快速统计,单词也可以快速的索引.缺点是内存消耗大 http://blog.csdn.net/chenleixing/article/de ...
- 『动善时』JMeter基础 — 32、JMeter察看结果树组件详解
目录 1.察看结果树介绍 2.察看结果树界面详解 3.察看结果树的其他功能 (1)将数据写入文件中 (2)Search功能 (3)Scroll automatically选项 4.总结 1.察看结果树 ...
- Trie树(字典树,单词查找树)详解+题目
什么是字典树? 叫前缀树更容易理解 字典树的样子 Trie又被称为前缀树.字典树,所以当然是一棵树.上面这棵Trie树包含的字符串集合是{in, inn, int, tea, ten, to}.每个节 ...
- 字典树trie的学习与练习题
博客详解: http://www.cnblogs.com/huangxincheng/archive/2012/11/25/2788268.html http://eriol.iteye.com/bl ...
- 字典树(Trie Tree)
在图示中,键标注在节点中,值标注在节点之下.每一个完整的英文单词对应一个特定的整数.Trie 可以看作是一个确定有限状态自动机,尽管边上的符号一般是隐含在分支的顺序中的.键不需要被显式地保存在节点中. ...
- 字典树(Trie树)实现与应用
一.概述 1.基本概念 字典树,又称为单词查找树,Tire数,是一种树形结构,它是一种哈希树的变种. 2.基本性质 根节点不包含字符,除根节点外的每一个子节点都包含一个字符 从根节点到某一节点.路径上 ...
- 字典树(Trie树)的实现及应用
>>字典树的概念 Trie树,又称字典树,单词查找树或者前缀树,是一种用于快速检索的多叉树结构,如英文字母的字典树是一个26叉树,数字的字典树是一个10叉树.与二叉查找树不同,Trie树的 ...
随机推荐
- 基于RT-Thread的开源飞控StarryPilot
背景描述 近年来无人机应用市场日趋火热,无人机开始被应用在多个领域之中,比如航拍,植保,运输,安防等.随着应用场景的增加,对于无人机的大脑一飞控,的性能和功能要求也变得越来越高.国内具有一大批优质的无 ...
- Java_零碎知识回顾
封装的理解 1.隐藏实现细节,控制对象的访问权限:对外提供公共方法: 隐藏:private 本类可见 继承的理解 ①父类有共性的属性与方法:子类只需要继承,扩展自己独有的属性方法即可,实现了代码的可复 ...
- Vue中兄弟组件间传值-(Bus/总线/发布订阅模式/观察者)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 真伪随机数 ——Random和SecureRandom
Random Random用来创建伪随机数.所谓伪随机数,是指只要给定一个初始的种子,产生的随机数序列是完全一样的. 要生成一个随机数,可以使用nextInt().nextLong().nextFlo ...
- VMware中Bridged、NAT、host-only三种网络连接模式的原理及其区别
VMnet0:这是VMware用于虚拟桥接网络下的虚拟交换机: VMnet1:这是VMware用于虚拟Host-Only网络下的虚拟交换机: VMnet8:这是VMware用于虚拟NAT网络下的虚拟交 ...
- CodeForces - 1059C Sequence Transformation (GCD相关)
Let's call the following process a transformation of a sequence of length nn. If the sequence is emp ...
- javascript对url进行编码和解码
这里总结下JavaScript对URL进行编码和解码的三个方法. 为什么要对URL进行编码和解码 只有[0-9[a-Z] $ - _ . + ! * ' ( ) ,]以及某些保留字,才能不经过编码直接 ...
- [ASP.NET Core 3框架揭秘] 依赖注入[3]:依赖注入模式
IoC主要体现了这样一种设计思想:通过将一组通用流程的控制权从应用转移到框架之中以实现对流程的复用,并按照"好莱坞法则"实现应用程序的代码与框架之间的交互.我们可以采用若干设计模式 ...
- 1、看源码MVC如何实例化控制器?
我们知道MVC请求进来,然后路由匹配,然后找到控制器和Action,最后会调用Action方法,但是大家想想控制器是个普通的类,Action是个普通的实例方法,要想调用Action必须先实例化控制器, ...
- 信通院发布《云计算发展白皮书 (2019年) 》 (附PPT解读)
来源: 中国信息通信研究院CAICT 为了进一步促进云计算创新发展,建立云计算信任体系,规范云计算行业,促进市场发展,提升产业技术和服务水平.由中国信息通信研究院(以下简称“中国信通院”)主办,中国通 ...