写在前面

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. c++11のunique_lock和once_flag

    一. Unique _lock和lockguard一样,到那时比lockguard更加灵活,可以随时按照需要加锁开锁 std::unique_lock<std::mutex> locker ...

  2. 8-过滤器Filter和监听器Listener

    一.web监听器:监听特殊事件的发生1.监听实现步骤 a.写一个java类,实现特定的接口,重写相关方法 b.在web.xml中,牌配置 <listener> <listener-c ...

  3. python之zip打包

    import zipfile # 压缩 z = zipfile.ZipFile('z.zip', 'w') z.write('xo.xml') z.write('xxxoo.xml') z.close ...

  4. UI Automator 常用 API 整理

    主要类: import android.support.test.uiautomator.UiDevice; 作用:设备封装类,测试过程中获取设备信息和设备交互. import android.sup ...

  5. python2.7添加注释后,代码无法保存

    最近需要学习一下Python,然后开始学习中,使用的编辑环境是Python自带的IDLE Python的注释使用的是   # 然后我再代码添加注释 #Python的注释是这个字符 发现始终无法保存代码 ...

  6. WPF防止界面卡死并显示加载中效果

    原文:WPF防止界面卡死并显示加载中效果 网上貌似没有完整的WPF正在加载的例子,所以自己写了一个,希望能帮到有需要的同学 前台: <Window x:Class="WpfApplic ...

  7. 全国天气预报信息数据 API 功能简介与代码调用实战视频

    此文章对开放数据接口 API 之「全国天气预报信息数据 API」进行了功能介绍.使用场景介绍以及调用方法的说明,供用户在使用数据接口时参考之用,并对实战开发进行了视频演示. 1. 产品功能 接口开放了 ...

  8. MySQL 字符串 分割 多列

    mysql如何进行以,分割的字符串的拆分 - 我有一个梦想 - CSDN博客https://blog.csdn.net/u012009613/article/details/52770567 mysq ...

  9. json 百分比转化

    NumberFormat number = NumberFormat.getPercentInstance(); number.setMaximumFractionDigits(0);//设置小数点后 ...

  10. "unexpected console statement” in Node.js

    .eslintrc.js module.exports = { rules: { 'no-console': 'off', }, };