字典树(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树的 ...
随机推荐
- cookie、session和token那些事
cookie 和 session 众所周知,HTTP 是一个无状态协议,所以客户端每次发出请求时,下一次请求无法得知上一次请求所包含的状态数据,如何能把一个用户的状态数据关联起来呢? 比如在淘宝的某个 ...
- 【Web技术】 275- 理解 WebView
前言 了解webview的神秘之处.今日早读文章由@子非翻译分享. 正文从这开始-- 我们通常使用 Chrome, Firefox, Safari, Internet Explorer 和 Edge ...
- 【Selenium】自动进入网页,出现弹窗被卡住
问题现象: 使用命令:driver.get("http://127.0.0.1/zentao/user-login.html") 进入网页,出现如下弹窗,无法进入 解决方法: #d ...
- 【Java Web开发学习】Spring加载外部properties配置文件
[Java Web开发学习]Spring加载外部properties配置文件 转载:https://www.cnblogs.com/yangchongxing/p/9136505.html 1.声明属 ...
- poj 3279 Fliptile (简单搜索)
Fliptile Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 16558 Accepted: 6056 Descrip ...
- java基础面向对象总结(一)
年底了,总结下知识点和遇到过的面试题目. 1,如何理解面相对象. ‘万物皆对象’说的没错,听起来挺反感的,问一个说一个.有些话觉得用自己的话讲出来肯俗点,但可以证明你理解了一点.我理解的是:之所以叫面 ...
- Go语言底层知识总结【新手必学】
前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理.作者:YID_152接下来我们来给大家分享想go的基础知识要点:如果你也刚学 ...
- wpf键盘
一.键盘类和键盘事件 WPF提供了基础的键盘类(System.Input.Keyboard类),该类提供与键盘相关的事件.方法和属性,这些事件.方法和属性提供有关键盘状态的信息.Keyboard的事件 ...
- SpringBoot之【mybatisplus】代码生成器
1.概述. AutoGenerator 是 MyBatis-Plus 的代码生成器,通过 AutoGenerator 可以快速生成 Entity.Mapper.Mapper XML.Service.C ...
- Python--合并2个字典成1个新字典的9种方法
d1 = {'name': 'revotu', 'age': 99} d2 = {'age': 24, 'sex': 'male'} 输出: {'name': 'revotu', 'age': 24, ...