写在前面

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. MAC oh-my-zsh

    效果图 step1 : 安装zsh    brew install zsh step2: sudo vim  /etc/shells 添加 /usr/local/bin/zsh  step3:安装oh ...

  2. CMD 和 Git 中的代理设置

    CMD 设置代理 在 cmd 环境下设置代理可能不是很常用,但是某些情况下还是可能会用到,比如公司的电脑只能通过设置代理访问外网,而你需要在 cmd 环境下使用 gem 命令更新文件时. 当然,如果你 ...

  3. Topshelf:一款非常好用的 Windows 服务开发框架

    背景 多数系统都会涉及到“后台服务”的开发,一般是为了调度一些自动执行的任务或从队列中消费一些消息,开发 windows service 有一点不爽的是:调试麻烦,当然你还需要知道 windows s ...

  4. 微信小程序测试

    1.连接真机,微信已经登录过了 2.代码: 3.appium自带的识别工具 4.设置工具连接设备的方式 参考资料: https://www.cnblogs.com/yoyoketang/p/91449 ...

  5. 货车运输-洛谷-1967-LCA+最大生成树(kruskal(并查集))

    传送门 一道:LCA+最大生成树 个人认为把这两个的板子写好(并熟练掌握了之后)就没什么难的 (但我还是de了好久bug)qwq 最大生成树:其实就是最小生成树的变形 我用的是kruskal (个人觉 ...

  6. 越狱解决iphone4s外放无声音

    删除iphone中/System/Library/PrivateFrameworks/IAP.framework/Support/目录下的iapd文件 进入/SYSTEM/Library/Launch ...

  7. iscroll.js实现上拉刷新,下拉加载更多,应用技巧项目实战

    上拉刷新,下拉加载更多...仿原生的效果----iscroll是一款做滚动效果的插件,具体介绍我就不废话,看官方文档,我只写下我项目开发的一些用到的用法: (如果不好使,调试你的css,想必是个很蛋疼 ...

  8. 第四章· Redis的事务、锁及管理命令

    一.事务介绍 二.Redis乐观锁介绍 三.Redis管理命令 一.事务介绍 Redis的事务与关系型数据库中的事务区别 1)在MySQL中讲过的事务,具有A.C.I.D四个特性 Atomic(原子性 ...

  9. Python可变参数*和**

    可变参数 在Python函数中,还可以定义可变参数.顾名思义,可变参数就是传入的参数个数是可变的,可以是1个.2个到任意个,还可以是0个. 我们以数学题为例子,给定一组数字a,b,c……,请计算a2 ...

  10. 使用Node.js搭建数据爬虫crawler

    0. 通用爬虫框架包括: (1) 将爬取url加入队列,并获取指定url的前端资源(crawler爬虫框架主要使用Crawler类进行抓取网页) (2)解析前端资源,获取指定所需字段的值,即获取有价值 ...