字典树(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得到了一本好厉害的字典,这个字典里 ... 
随机推荐
- 每日学习——iframe标签伪造ajax
			刚开始学习ajax,好难,看不懂啊看不懂. 伪造ajax加载网页 <!DOCTYPE html> <html> <head lang="en"> ... 
- Docker系列(3)- 配置阿里云镜像加速
			step-1 登录阿里云找到容器服务 step-2 找到镜像加速地址 step-3 配置使用 sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon ... 
- oracle 基础SQL语句 版本5.7.29
			一.表与用户介绍 oracle安装完成后默认会有很多用户,大致分为2类用户:一类是必需的帐户,一类是存储各种应用的帐户,默认密码如下: oracle自带的也会有很多默认表存在: 二.创建用户.创建表空 ... 
- php 常用算法与函数
			1.一群猴子排成一圈,按1,2,-,n依次编号.然后从第1只开始数,数到第m只,把它踢出圈,从它后面再开始数,再数到第m只,在把它踢出去-,如此不停的进行下去,直到最后只剩下一只猴子为止,那只猴子就叫 ... 
- Python - with 语句
			管理外部资源的背景 在编程中会面临的一个常见问题是如何正确管理外部资源,例如文件.锁和网络连接 有时,程序会永远保留这些资源,即使不再需要它们,这种现象称为内存泄漏 因为每次创建和打开给定资源的新实例 ... 
- CF235C-Cyclical Quest【SAM】
			正题 题目链接:https://www.luogu.com.cn/problem/CF235C 题目大意 一个文本串\(s\).询问\(n\)个匹配的本质不同的循环同构在文本串中出现了几次. 解题思路 ... 
- T183637-变异距离(2021 CoE III C)【单调栈】
			正题 题目链接:https://www.luogu.com.cn/problem/T183637 题目大意 给出\(n\)个二元组\((x_i,y_i)\),求最大的 \[|x_i-x_j|\time ... 
- pkusc2021游记
			@ 目录 前言 Day 0 Day 1 Day 2 Day 3 前言 到时候APIO的大概也会写在这篇里吧. Day 0 车,公交,飞机,公交,车 坐了半天的交通终于到了,整个人都坐的晕乎乎的,然后看 ... 
- CF453C-Little Pony and Summer Sun Celebration【构造】
			正题 题目链接:https://www.luogu.com.cn/problem/CF453C 题目大意 \(n\)个点\(m\)条边的一张无向图,每个节点有一个\(w_i\)表示该点需要经过奇数/偶 ... 
- MacOS下terminal防止ssh自动断开的方法和自动断开的原因
			之前换了个工作环境,用terminal连接远程服务器的时候老是出现自动断开的情况,搞得我很是郁闷.因为之前在家的时候,并没有出现过类似情况.后来在网上找了很久,发现国外网站上有个大神说应该是有些路由器 ... 
