Trie树的二三事QWQ
写在前面
Trie,又称字典树,是一种用于实现字符串快速检索的多叉树结构。Trie的每个结点都拥有若干字符指针,若在插入或检索字符串时扫描到一个字符c,就沿着当前节点的c这个字符指针,走向该指针指向的结点。
我的没有指针的版本理解:树上的每个结点都记录了两个信息,一是这个结点所代表的字符,二是这个字符是否是一个字符串的结尾
正文:Trie树的基本操作
一、建立一棵Trie树
1.初始化
一棵空Trie树仅包含一个根结点,这个根结点不代表任何字符
2.插入
当需要插入一个字符串S时,我们从根结点开始,扫描当前树上结点的所有子结点,同时与字符串中当前这一位的字符匹配,于是就可能出现两种情况:
<1>匹配成功,当前树上的这个结点恰好有一个子结点代表的是字符串中当前这一位的字符,则直接开始扫描这个子结点的所有子结点,去匹配字符串中的下一位字符
<2>匹配失败,那么我们就给树上的这个结点增加一个子结点代表字符串中当前这一位的字符,然后继续进程
要注意的一点是,如果当前的这个字符是字符串中的最后一位,那么就要在树上的相应结点处记录一下。
这样干讲484有点难懂?让我来举个栗子吧QAQ
假设我现在要插入的字符串是stark(没错我就是漫威死忠粉还有我本来想插一个Marvel的但是太长了)
目前的Trie数是酱紫的
然后我现在要开始往里插入啦!当前状态是扫描到树上的根结点&字符串的第1位
如上所述我现在要在根结点的子结点中查找代表了字符“s”的结点
转化成图就是酱紫哒
此时就是我说道的第<1>种情况,我们发现根结点的子结点中恰好有一个结点可以与字符串中的这一位匹配,于是我们继续操作……
同样的,“t”也可以匹配,那我们就继续往下走……
现在扫描到代表t的结点,发现它的子结点中没有能和字符串中当前这一位“a”相匹配的,于是我们就给代表t的结点插入一个子结点代表a
就是酱紫啦!然后我们再继续往下操作……
中间过程我就省略啦,重复之前的步骤就好QWQ
一个世纪之后……我们的Trie树就变成了这个样子
最后别忘了在代表字符串结尾字符的结点打上标记哦
好啦,到此为止,我们就完成了向Trie树中插入一个字符串的操作啦!^_^
3.代码实现
struct T{
bool end;//是否为字符串结尾
int son[];
//表示子结点中此种字符的编号(存在位置),这里假设是26个小写字母
char ch;//当前结点所代表的字符(其实这个可以不要QAQ)
}Trie[max_point];//max_point为最大结点数目
void build(string s){//s是要插入Trie树的字符串
int len=s.length();
int now=;
for(int i=;i<len;i++){
if(!Trie[now].son[s[i]-'a']){//如果子结点中不存在这个字符
Trie[now].son[s[i]-'a']=++num;//num记录总结点数
Trie[num].ch=s[i];
}//构建出这个结点
now=Trie[now].son[s[i]-'a'];//继续访问
}
Trie[now].end=;//标记字符串结尾
}
应该是对的吧,我也没有试过呀QAQ(瑟瑟发抖的蒟蒻)
二、在Trie树上进行检索
当需要检索一个字符串S在Trie中是否存在时,我们可以像插入操作一样去扫描。
检索的结果无非就是存在和不存在两种情况
存在很简单,而对于不存在,同样会有两种情况
1.在匹配字符串中的字符和Trie树上的结点时,出现Trie树上不存在代表字符串中的某一个字符的情况,那么显然这个字符串就不可能存在于Trie树中了
2.匹配时字符串中的每一个字符都按顺序存在与Trie树中,但Trie树中代表字符串中最后一个字符的结点没有被标记为字符串结尾,那么这个字符串同样也是不存在于Trie树中的
就拿我们刚刚建立的Trie树举个栗子吧
现在我要检索三个字符串是否存在于Trie树中
这三个字符串分别是“maya”“soldier”“pet”(字符串不包括“”)
我们先来检索“maya”
字符串的每一位都匹配成功并且最后一位在Trie树中也标记了是结尾,所以可知字符串“maya”是存在于Trie树中的QWQ
接下来检索“soldier”
可以发现当匹配到字符串中的“o”字符时匹配失败,也就是我上面说到的第1种情况,因此可知“soldier”是不存在于Trie树中的。
最后我们来检索“pet”
在匹配过程中,“pet”的每一个字符都匹配成功了,但是匹配到最后一位时我们发现,代表“t”字符的这个结点没有被标记为字符串的结尾,这对应了我上面说到的第2种情况,所以最后可知“pet”也是不存在于Trie树中的。
好啦就是酱紫……我放了一份代码啦!
bool exist(string s){//s是要检索的字符串
int len=s.length();
int now=;//从根结点(编号为0)开始
for(int i=;i<len;i++){//逐位匹配
if(!Trie[now].son[s[i]-'a']) return ;
now=Trie[now].son[s[i]-'a'];
}
if(Trie[now].end) return ;
else return ;
}
Trie树的二三事QWQ的更多相关文章
- Trie树(字典树)(1)
Trie树.又称字典树,单词查找树或者前缀树,是一种用于高速检索的多叉树结构. Trie树与二叉搜索树不同,键不是直接保存在节点中,而是由节点在树中的位置决定. 一个节点的全部子孙都有同样的前缀(pr ...
- 洛谷$P4585\ [FJOI2015]$火星商店问题 线段树+$trie$树
正解:线段树+$trie$树 解题报告: 传送门$QwQ$ $umm$题目有点儿长我先写下题目大意趴$QwQ$,就说有$n$个初始均为空的集合和$m$次操作,每次操作为向某个集合内加入一个数$x$,或 ...
- [十二省联考2019]异或粽子——可持久化trie树+堆
题目链接: [十二省联考2019]异或粽子 求前$k$大异或区间,可以发现$k$比较小,我们考虑找出每个区间. 为了快速得到一个区间的异或和,将原序列做前缀异或和. 对于每个点作为右端点时,我们维护出 ...
- 查找(二)简单清晰的B树、Trie树具体解释
查找(二) 散列表 散列表是普通数组概念的推广.因为对普通数组能够直接寻址,使得能在O(1)时间内訪问数组中的任何位置.在散列表中,不是直接把keyword作为数组的下标,而是依据keyword计算出 ...
- 标准Trie字典树学习二:Java实现方式之一
特别声明: 博文主要是学习过程中的知识整理,以便之后的查阅回顾.部分内容来源于网络(如有摘录未标注请指出).内容如有差错,也欢迎指正! 系列文章: 1. 标准Trie字典树学习一:原理解析 2.标准T ...
- 【洛谷5283】[十二省联考2019] 异或粽子(可持久化Trie树+堆)
点此看题面 大致题意: 求前\(k\)大的区间异或和之和. 可持久化\(Trie\)树 之前做过一些可持久化\(Trie\)树题,结果说到底还是主席树. 终于,碰到一道真·可持久化\(Trie\)树的 ...
- 字典(trie)树--从入门到入土
今天再来认识一个强大的数据结构. 字典树又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种.典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词 ...
- Trie树-字典查找
描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程的学习道路上一同前进. 这一天,他们遇到了一本词典,于是小Hi就向小Ho提出了那个经典的问题: ...
- Trie树(c++实现)
转:http://www.cnblogs.com/kaituorensheng/p/3602155.html http://blog.csdn.net/insistgogo/article/detai ...
随机推荐
- Redis内存优化memory-optimization
https://redis.io/topics/memory-optimization 官方文档 一.特殊编码: 自从Redis 2.2之后,很多数据类型都可以通过特殊编码的方式来进行存储空间的优化 ...
- Koa 中 ejs 模板的使用
ejs的基本使用 安装 koa-views 和 ejs npm install --save koa-views/cnpm install --save koa-views npm install e ...
- 做自己的docker镜像(基于ubuntu:16.04)
基于ubuntu:16.04 apt-get update -y apt-get install sudo -y 换源 sudo apt-get install vim sudo vim /etc/a ...
- HttpServletResponse简单理解
Web服务器收到一个http请求,会针对每个请求创建一个HttpServletRequest和HttpServletResponse对象,从客户端取数据用HttpServletRequest,向客户端 ...
- 【Atcoder Grand Contest 011 F】Train Service Planning
题意:给\(n+1\)个站\(0,\dots,n\),连续的两站\(i-1\)和\(i\)之间有一个距离\(A_i\),其是单行(\(B_i=1\))或双行(\(B_i=2\)),单行线不能同时有两辆 ...
- 使用html2canvas.js实现页面截图并显示或上传
最近写项目有用到html2canvas.js,可以实现页面的截图功能,但遭遇了许多的坑,特此写一篇随笔记录一下. 在使用html2canvas时可能会遇到诸如只能截取可视化界面.截图没有背景色.svg ...
- vue 图片懒加载 vue-lazyload
图片懒加载 在实际的项目开发中,我们通常会遇见这样的场景:一个页面有很多图片,而首屏出现的图片大概就一两张,那么我们还要一次性把所有图片都加载出来吗?显然这是愚蠢的,不仅影响页面渲染速度,还浪费带宽. ...
- Jquery mobile动态生成ListView调用刷新方法报错
错误:cannot call methods on listview prior to initialization... 示例: <div data-role="page" ...
- 控制结构(6): 最近最少使用(LRU)
// 上一篇:必经之地(using) // 下一篇:程序计数器(PC) 基于语言提供的基本控制结构,更好地组织和表达程序,需要良好的控制结构. There are only two hard thin ...
- Linux 默认连接数
Linux 默认连接数 - 国内版 Binghttps://cn.bing.com/search?FORM=U227DF&PC=U227&q=Linux+%E9%BB%98%E8%AE ...