字典树(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得到了一本好厉害的字典,这个字典里 ...
随机推荐
- CVPR顶会论文爬取存入MySQL数据库(标题、摘要、作者、PDF链接和原地址)
main.py import pymysql import re import requests # 连接数据库函数 from bs4 import BeautifulSoup def insertC ...
- vscode快速添加引号 批量增加引号(用于批量格式化代码)
一.在浏览器中将Params复制到pycharm的py文件中 二.选中需要添加引号的部分,Ctrl+H 调出替换工具栏 三.填写正则表达式 (.*?): (.*) '$1':'$2', 右侧注意点击使 ...
- DEDE判断当前是否有下级栏目,有就显示所有下级栏目,没有就显示同级栏目!
{dede:channel name='type' runphp='yes' if(reid == "0") @me = "son";else @me = &q ...
- 【Azure 应用服务】App Service For Linux 部署PHP Laravel 项目,如何修改首页路径为 wwwroot\public\index.php
问题描述 参考官方文档部署 PHP Laravel 项目到App Service for Linux环境中,但是访问应用时候遇见了500 Server Error 错误. 从部署的日志中,可以明确看出 ...
- 华为云计算IE面试笔记-FusionCompute上的虚拟机A和虚拟机B不能正常通信,请描述可能的故障点和排除方法(分析虚拟机A和虚拟机B不通)
*快速定位故障点:(考到) ARP:同一二层内可以通过ARP -a命令查询到要访问的主机IP(ARP表项中记录了同一二层中的IP和MAC的对应关系),若查询不到,说明二层出现问题(Vlan 间不通)或 ...
- AVS 端能力之蓝牙模块
该类为蓝牙端能力处理类,主要负责蓝牙设备配对和蓝牙音频播放功能. 功能简介 实现蓝牙设备的启动发现模式.扫描蓝牙设备.建立蓝牙连接功能 实现蓝牙设备音频播放.停止.上一首.下一首功能 其它细节参考&l ...
- Winform配置文件读写操作
前言 在项目当中为了增加软件的灵活性及可配置性,配置文件在程序当中起着不可替代的作用.下面介绍一下最近用的比较多的方式. config文件的操作 数据库连接字符串 1.获取连接字符串 public s ...
- 01Prism WPF 入门实战 - 项目准备
1.概要 这一系列将进行Prism+WPF技术的实战讲解.实战项目内容选型为Email邮件收发的客户端(WeMail),项目结构简单方便大家理解. 相关技术:C#.WPF.Prism 软件开发环境:V ...
- 11.4.5 LVS负载均衡常见工作模式总结以及ipvsadm
NAT TUN DR RS any Tunneling Non-arp device RS network private LAN/WAN LAN RS number low(10-20) Hig ...
- 3D Analyst Tools(3D Analyst 工具)
3D Analyst 工具 工具里有又细分如下分类: 注:以下代码的参数需要另行配置,不能直接执行:Python2不支持中文变量! 1.3D 要素 # Process: 3D 内部 arcpy.Ins ...