写在前面

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的更多相关文章

  1. Trie树(字典树)(1)

    Trie树.又称字典树,单词查找树或者前缀树,是一种用于高速检索的多叉树结构. Trie树与二叉搜索树不同,键不是直接保存在节点中,而是由节点在树中的位置决定. 一个节点的全部子孙都有同样的前缀(pr ...

  2. 洛谷$P4585\ [FJOI2015]$火星商店问题 线段树+$trie$树

    正解:线段树+$trie$树 解题报告: 传送门$QwQ$ $umm$题目有点儿长我先写下题目大意趴$QwQ$,就说有$n$个初始均为空的集合和$m$次操作,每次操作为向某个集合内加入一个数$x$,或 ...

  3. [十二省联考2019]异或粽子——可持久化trie树+堆

    题目链接: [十二省联考2019]异或粽子 求前$k$大异或区间,可以发现$k$比较小,我们考虑找出每个区间. 为了快速得到一个区间的异或和,将原序列做前缀异或和. 对于每个点作为右端点时,我们维护出 ...

  4. 查找(二)简单清晰的B树、Trie树具体解释

    查找(二) 散列表 散列表是普通数组概念的推广.因为对普通数组能够直接寻址,使得能在O(1)时间内訪问数组中的任何位置.在散列表中,不是直接把keyword作为数组的下标,而是依据keyword计算出 ...

  5. 标准Trie字典树学习二:Java实现方式之一

    特别声明: 博文主要是学习过程中的知识整理,以便之后的查阅回顾.部分内容来源于网络(如有摘录未标注请指出).内容如有差错,也欢迎指正! 系列文章: 1. 标准Trie字典树学习一:原理解析 2.标准T ...

  6. 【洛谷5283】[十二省联考2019] 异或粽子(可持久化Trie树+堆)

    点此看题面 大致题意: 求前\(k\)大的区间异或和之和. 可持久化\(Trie\)树 之前做过一些可持久化\(Trie\)树题,结果说到底还是主席树. 终于,碰到一道真·可持久化\(Trie\)树的 ...

  7. 字典(trie)树--从入门到入土

    今天再来认识一个强大的数据结构. 字典树又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种.典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词 ...

  8. Trie树-字典查找

    描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程的学习道路上一同前进. 这一天,他们遇到了一本词典,于是小Hi就向小Ho提出了那个经典的问题: ...

  9. Trie树(c++实现)

    转:http://www.cnblogs.com/kaituorensheng/p/3602155.html http://blog.csdn.net/insistgogo/article/detai ...

随机推荐

  1. Android图片选择---MultiImageSelector的使用

    Github地址:https://github.com/lovetuzitong/MultiImageSelector MultiImageSelector主要是图片选择功能. AndroidStud ...

  2. 服务网关Ocelot 入门Demo系列(01-Ocelot极简单Demo及负载均衡的配置)

    [前言] Ocelot是一个用.NET Core实现并且开源的API网关,它功能强大,包括了:路由.请求聚合.服务发现.认证.鉴权.限流熔断.并内置了负载均衡器与Service Fabric.Butt ...

  3. JShell脚本工具

    JShell脚本工具是JDK9的新特性 什么时候会用到 JShell 工具呢,当我们编写的代码非常少的时候,而又不愿意编写类,main方法,也不愿意去编译和运行,这个时候可以使用JShell工具.启动 ...

  4. 安装inotify-tools监控工具

    安装inotify-tools监控工具 yum install -y inotify-tools 2:查看inotify-tools包的工具程序 [root@dns3 ~]# rpm -ql inot ...

  5. idea中war和war exploded的区别及修改jsp必须重新启动tomcat才能生效的问题

    刚开始使用idea,发现工程每次修改JS或者是JSP页面后,并没有生效,每次修改都需要重启一次Tomcat这样的确不方便.我想Idea肯定有设置的方法,不可能有这么不方便的功能存在. 需要在Tomca ...

  6. Python pip Unable--

    It is possible that pip does not get installed by default. One potential fix is: python -m ensurepip ...

  7. P2822 组合数问题 HMR大佬讲解

    今天HMR大佬给我们讲解了这一道难题. 基本思路是: 可以将问题转化为:求出杨辉三角,用二维数组f[i][j]来表示在杨辉三角中以第i行第j列的点为右下角,第0行第0列处的点为左上角的矩阵中所有元素是 ...

  8. Django+Vue打造购物网站(七)

    个人中心功能开发 drf文档注释 http://www.django-rest-framework.org/topics/documenting-your-api/ 动态设置serializer和pe ...

  9. Vivado如何使用命令行创建工程

    前言 vivado中采用TCL脚本语言来作为其命令解释语言.除去可以普通的图形界面流程还可以使用tcl脚本创建工程并导入相关源文件.   流程 1.首先还是要打开vivado图形主界面. 2.在某路径 ...

  10. Django_modelform组件

    modelForm 组件 概念 将数据库与form 组件结合用起来的中间插件 与 form 组件的区别 form组件的难处: form 可以实现 对数据的验证以及 form 的表单标签的生成 但是她做 ...