字典树(Trie)
终于学会字典树了,真开心(然后就滚过来写总结了)。
首先,字典树到底是个什么东西呢?请看下面这段话:
字典树,常被用来保存与查找大量的字符串,它利用了字符串之间的公共前缀来节约时间,但它的空间花费较大。 ——整理自百度百科
举个例子,现在有六个字符串,分别是:“he”、“her”、“sheep”、“she”、“shem”、“me”,用这几个字符串构造的trie就长下面这样:
我们可以发现,在trie中,除了根节点,其它的每个节点都代表着一个字符。如果节点是灰色的,就表示此节点是一个字符串结束的位置。
我们先来看一看trie是如何运作的吧。
比如说,我现在要“her”这一个字符串是否存在,我们就只需要顺着树边往下找,像下面这样子:
如果可以一直顺着树边找到结束,并且结束点是一个灰色节点,那么就说明“her”这一个字符串是存在的。
再举个例子,假如现在要判断的是“hen”这一个字符串是否存在(显然它是不存在的),我们也是像刚才那样子顺着树边往下找:
可以发现,这一次我们在走到“e”这一个节点后就没有看到储存的字符为“n”的节点了,这就说明“hen”这一个字符串是不存在的。
说到这里,大家对trie的基本功能应该已经有了一个比较清晰的认识了。有人可能会说,判断一个字符串在一个字符串集合中是否存在,直接用哈希不就搞定了吗?是的,确实是这样。不过trie更容易扩展。比如说,AC自动机就是在trie上使用了kmp算法的思想实现的。所以,学习trie还是很有必要的。
好,说了这么多理论,我们接下来就来说一下trie树的实现思路吧。
首先肯定是讲如何在一棵trie中插入字符串了。在trie中插入字符串的思路很简单,我们来举个例子(举例子大法好啊),比如说现在我们要在一棵空trie中插入一个字符串“”sheep”。首先,一棵空trie是下面这样子的:
(只有一个根节点,而且这个根节点不储存任何字符信息)
然后,我们来弄一个箭头指向这个根节点,表示我们现在的位置就是在这个根节点:
接下来,我们来插入“sheep”中的第一个字符“s”,因为当前箭头指向的节点并没有“s”这个儿子,所以我们来新建一个,并将箭头指向这一个“s”:
紧接着,像上面那样依次插入“sheep”的后几个字符:“h”、“e”、“e”、“p”:
将“sheep”中的所有字符全部插入完毕后,我们再将当前箭头指向的节点标记为灰色,表示这一个结点是“sheep”这一个字符串的结束位置,这个应该很容易理解吧?如下图所示:
这样我们就将“sheep”插入到这一棵trie中了,但是如果我们还要插入一个字符串“shem”的话,又该怎么处理呢?我们再来模拟一下。
首先,箭头肯定是指向根节点:
然后,我们看一下“shem”的第一个字符“s”。唉?当前节点已经有儿子“s”了,那我们就直接指向那里:
接着,我们看一下“shem”的第二个字符“h”,唉?当前节点已经有儿子“h”了,那我们还是直接指向那里:
接下来,我们看一下“shem”的第三个字符“e”,唉?当前节点已经有儿子“e”了,那我们还是直接指向那里:
紧接着,我们看一下“shem”的第四个字符“m”,唉?当前节点没有儿子“m”,那我们就新建一个儿子节点“m” ,然后指向那里:
最后标记成灰色就好啦!
综上所述,trie的插入思路可以总结为一点:如果有就直接上,没有就新建。(是不是很精辟)
trie的插入代码如下:
int tot=0,tri[size][26];
bool end[size];
void cr(char* st)
{
int len=strlen(st),p=1;//p就是那个“箭头”
for(int i=0;i<len;i++)//依次插入这个字符串的每一个字符
{
int t=st[i]-97;
if(tri[p][t]==0) tri[p][t]=++tot;//如果没有符合要求的节点就新建
p=tri[p][t];//“箭头”指向下一个节点
}
end[p]=true;//标记当前节点为灰色(就是标记当前节点是一个字符串的结束位置)
}
上面的代码中的size为给出的所有字符串中字符数量的总和,因为最糟糕的情况就是将每个字符都建了一个节点,所以trie的节点最多也不会超过所有字符串中字符数量的总和。
把tri数组的第二维定为26是因为trie处理的字符串一般都是只由26个小写英文字母组成的(当然,trie也能处理其它字符串,这里只是“一般”而已),这要视情况而定。
那么trie的查找操作呢?这个前面其实已经讲过了,这和插入的思路是大同小异的,那就直接丢代码吧:
bool cz(char* st)
{
int len=strlen(st),p=1;//p就是那个“箭头”
for(int i=0;i<len;i++)//依次查找这个字符串的每一个字符
{
int t=st[i]-97;
if(tri[p][t]==0) return false;//如果没有符合要求的节点就说明找不到了
p=tri[p][t];//“箭头”指向下一个节点
}
if(end[p]) return true;//如果当前节点是某个字符串的结束位置就说明找到了
return false;//否则就说明找不到了
}
如果明白了插入操作是肯定可以看得懂上面的代码的,基本上是如法炮制。
从上述代码不难看出trie插入与删除的时间复杂度都是O(L)的,其中L为插入或查找的字符串的长度,trie的时间复杂度还是挺优秀的嘛。
trie裸题: Luogu P2580 于是他错误的点名开始了
好了,终于写完了。。。
由于博主是个蒟蒻,所以肯定会有一些地方写得不清楚,还请大家批评指正。
0=w=0
字典树(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 ...
- 字典树(Trie)详解
详解字典树(Trie) 本篇随笔简单讲解一下信息学奥林匹克竞赛中的较为常用的数据结构--字典树.字典树也叫Trie树.前缀树.顾名思义,它是一种针对字符串进行维护的数据结构.并且,它的用途超级广泛.建 ...
- 字典树(Trie Tree)
在图示中,键标注在节点中,值标注在节点之下.每一个完整的英文单词对应一个特定的整数.Trie 可以看作是一个确定有限状态自动机,尽管边上的符号一般是隐含在分支的顺序中的.键不需要被显式地保存在节点中. ...
- 字典树(Trie树)实现与应用
一.概述 1.基本概念 字典树,又称为单词查找树,Tire数,是一种树形结构,它是一种哈希树的变种. 2.基本性质 根节点不包含字符,除根节点外的每一个子节点都包含一个字符 从根节点到某一节点.路径上 ...
- 字典树(Trie树)的实现及应用
>>字典树的概念 Trie树,又称字典树,单词查找树或者前缀树,是一种用于快速检索的多叉树结构,如英文字母的字典树是一个26叉树,数字的字典树是一个10叉树.与二叉查找树不同,Trie树的 ...
- 字典树trie的学习与练习题
博客详解: http://www.cnblogs.com/huangxincheng/archive/2012/11/25/2788268.html http://eriol.iteye.com/bl ...
- [转载]字典树(trie树)、后缀树
(1)字典树(Trie树) Trie是个简单但实用的数据结构,通常用于实现字典查询.我们做即时响应用户输入的AJAX搜索框时,就是Trie开始.本质上,Trie是一颗存储多个字符串的树.相邻节点间的边 ...
- Codevs 4189 字典(字典树Trie)
4189 字典 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 大师 Master 传送门 题目描述 Description 最经,skyzhong得到了一本好厉害的字典,这个字典里 ...
随机推荐
- ESP8266- AP模式的使用
打算通过该模式,利用手机APP完成配网 • AP,也就是无线接入点,是一个无线网络的创建者,是网络的中心节点.一般家庭或办公室使用的无线路由器就是一个AP. • STA站点,每一个连接到无线网络中的终 ...
- NOI.AC#2007-light【根号分治】
正题 题目链接:http://noi.ac/problem/2007 题目大意 \(n\)个格子排成一排,每个格子有一个\(0/1\)和一个颜色.开始每个格子都是\(0\),\(q\)次操作取反一个颜 ...
- P1912-[NOI2009]诗人小G【四边形不等式,单调队列】
正题 题目链接:https://www.luogu.com.cn/problem/P1912 题目大意 给出\(n\)个字符串,把这些字符串依次用空格(算一个长度)连接分成若干段,若一段长度为\(x\ ...
- 使用jacob调用Windows的com对象,进行word、ppt等转换成ptf、html(二)
富文本转pdf : 注意:simsun.ttc 可以百度下载:http://www.pc6.com/softview/SoftView_100415.html package com.orangecd ...
- python3之cx_Freeze使用(PyQt5)
1. cx_Freeze简介 Python脚本在装有Python的系统中可以直接双击运行,但绝大多数普通用户并没有配置此类环境,而编译为可执行二进制文件后,用户无需预先安装Python及依赖库即可 ...
- arcgis js4.x在geojson数据上点击显示弹窗,并添加删除按钮
实例geojsonLayer时添加属性popupTemplate popupTemplate: { title: action, content: '点击了' } 设置title用于查询到多个grap ...
- 14-Java锁的概述
14-锁的概述 乐观锁与悲观锁 乐观锁与悲观锁是数据库中引入的名词,但是在并发包里也引入了类似的思想,在这里我们还是有必要需要了解一下. 悲观锁指数据被外界修改持保守态度,认为数据会很容易被其 ...
- 使用CEF(一)— 起步
使用CEF(一)- 起步 介绍 Chromium Embedded Framework (CEF)是个基于Google Chromium项目的开源Web browser控件,支持Windows, Li ...
- MySQL5.7主从复制-异步复制搭建
两台服务器,系统是Redhat6.5,MySQL版本是5.7.18.1.在主库上,创建复制使用的用户,并授予replication slave权限.这里创建用户repl,可以从IP为10.10.10 ...
- Serverless 架构到底要不要服务器?
作者 | aoho 来源 | Serverless 公众号 Serverless 是什么? Serverless 架构是不是就不要服务器了?回答这个问题,我们需要了解下 Serverless 是什么. ...