详解字典树(Trie)

本篇随笔简单讲解一下信息学奥林匹克竞赛中的较为常用的数据结构——字典树。字典树也叫Trie树、前缀树。顾名思义,它是一种针对字符串进行维护的数据结构。并且,它的用途超级广泛。建议大家熟练掌握。

字典树的概念

字典树,顾名思义,是关于“字典”的一棵树。即:它是对于字典的一种存储方式(所以是一种数据结构而不是算法)。这个词典中的每个“单词”就是从根节点出发一直到某一个目标节点的路径,路径中每条边的字母连起来就是一个单词。

上图理解:

(标橙色的节点是“目标节点“,即根节点到这个目标节点的路径上的所有字母构成了一个单词。)

从这张图我们可以看出,字典树就是一棵树(emm...有些废话的嫌疑),只不过,这棵树的每条边上都有一个字母,然后这棵树的一些节点被指定成了标记节点(目标节点)而已。

这就是字典树的概念。结合上面说的概念,上图所示的字典树包括的单词分别为:

a
abc
bac
bbc
ca

字典树的功能

根据字典树的概念,我们可以发现:字典树的本质是把很多字符串拆成单个字符的形式,以树的方式存储起来。所以我们说字典树维护的是”字典“。那么根据这个最基本的性质,我们可以由此延伸出字典树的很多妙用。简单总结起来大体如下:

  • 1、维护字符串集合(即字典)。

  • 2、向字符串集合中插入字符串(即建树)。

  • 3、查询字符串集合中是否有某个字符串(即查询)。

  • 4、统计字符串在集合中出现的个数(即统计)。

  • 5、将字符串集合按字典序排序(即字典序排序)。

  • 6、求集合内两个字符串的LCP(Longest Common Prefix,最长公共前缀)(即求最长公共前缀)。

我们可以发现,以上列举出的功能都是建立在“字符串集合”的基础上的。再一次强调,字典树是“字典”的树,一切功能都是“字典”的功能。这也为我们使用字典树的时候提供了一个准则:看到一大堆字符串同时出现,就往哈希和Trie树那边想一下。

字典树的实现及代码实现

把上面的图搬下来...

字典树的两种基本操作分别是建树和查询。其中建树操作就是把一个新单词插入到字典树里。查询操作就是查询给定单词是否在字典树上。

那我们来想一下。

插入操作

假如这个字典只包括26个英文字母(暂且都定为小写),那么这个树的深度会由具体单词不一样而定。但是它的广度范围是可以提前确定好的。对于每个节点,广度最大为26。(因为每个节点的下一个字母(即后缀点)只可能是26个字母。)那么我们可以用结构体开好这个“虚拟全树”(这个名字是笔者自己起的,请大家好好理解)。然后通过深度迭代向里面尝试加入单词。

我们开一个包含\(26\)个后缀指针的结构体。用变量\(now\)来表示指向当前节点编号的一个指针,用\(tot\)变量表示点的编号。\(end\)数组表示当前单词的“目标节点”即单词结尾的那个节点具体是哪个单词的词尾。

那么代码就长成这样:

struct node
{
int nxt[27];
}trie[maxn]; int insert(char s[],int id)
{
int now=0;
int len=strlen(s);
for(int i=0;i<len;i++)
{
int ch=s[i]-'a'+1;
if(!trie[now].nxt[ch])
{
trie[now].nxt[ch]=tot;
tot++;
}
now=trie[now].nxt[ch];
}
end[now]=id;
}

查询操作

查询操作和刚刚的思路大同小异,因为我们已经有了一个“虚拟全树”,那么我们还是按深度向下迭代,对于需要查询的字符串的当前字符,如果这个对应的字符指针为空,就说明不含这个单词,直接跳出即可。当我们都迭代完成之后,直接返回\(end[now]\)即可。(注意,这里不能直接返回\(1\)或\(true\),假如字典中只保存了一个字符串\(abcdef\),而我们查询的是\(abc\),它可以不被跳出地一直迭代到最后,但是它并不是字典中的单词。即,需要考虑字典中单词子串的情况)。

代码:

bool search(char s[])
{
int len=strlen(s);
int now=0;
for(int i=0;i<len;i++)
{
int ch=s[i]-'a'+1;
if(!trie[now].nxt[ch])
return 0;
}
return end[now];
}

字典树(Trie)详解的更多相关文章

  1. [POJ] #1002# 487-3279 : 桶排序/字典树(Trie树)/快速排序

    一. 题目 487-3279 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 274040   Accepted: 48891 ...

  2. 『字典树 trie』

    字典树 (trie) 字典树,又名\(trie\)树,是一种用于实现字符串快速检索的树形数据结构.核心思想为利用若干字符串的公共前缀来节约储存空间以及实现快速检索. \(trie\)树可以在\(O(( ...

  3. 字典树trie学习

    字典树trie的思想就是利用节点来记录单词,这样重复的单词可以很快速统计,单词也可以快速的索引.缺点是内存消耗大 http://blog.csdn.net/chenleixing/article/de ...

  4. 『动善时』JMeter基础 — 32、JMeter察看结果树组件详解

    目录 1.察看结果树介绍 2.察看结果树界面详解 3.察看结果树的其他功能 (1)将数据写入文件中 (2)Search功能 (3)Scroll automatically选项 4.总结 1.察看结果树 ...

  5. Trie树(字典树,单词查找树)详解+题目

    什么是字典树? 叫前缀树更容易理解 字典树的样子 Trie又被称为前缀树.字典树,所以当然是一棵树.上面这棵Trie树包含的字符串集合是{in, inn, int, tea, ten, to}.每个节 ...

  6. 字典树trie的学习与练习题

    博客详解: http://www.cnblogs.com/huangxincheng/archive/2012/11/25/2788268.html http://eriol.iteye.com/bl ...

  7. 字典树(Trie Tree)

    在图示中,键标注在节点中,值标注在节点之下.每一个完整的英文单词对应一个特定的整数.Trie 可以看作是一个确定有限状态自动机,尽管边上的符号一般是隐含在分支的顺序中的.键不需要被显式地保存在节点中. ...

  8. 字典树(Trie树)实现与应用

    一.概述 1.基本概念 字典树,又称为单词查找树,Tire数,是一种树形结构,它是一种哈希树的变种. 2.基本性质 根节点不包含字符,除根节点外的每一个子节点都包含一个字符 从根节点到某一节点.路径上 ...

  9. 字典树(Trie树)的实现及应用

    >>字典树的概念 Trie树,又称字典树,单词查找树或者前缀树,是一种用于快速检索的多叉树结构,如英文字母的字典树是一个26叉树,数字的字典树是一个10叉树.与二叉查找树不同,Trie树的 ...

随机推荐

  1. linux—ln

    1.  软连接:不可删除源文件,删除源文件导致链接文件找不到,出现红色闪烁. 2.  硬链接:  源文件删除后,链接文件可以正常打开,链接前后的文件inode号相同,硬链接只能针对文件做链接,,不能针 ...

  2. Python3 数据结构之词频统计(英文)

    import string path = r'C:\Users\Black\Desktop\Walden.txt' with open(path, 'r', encoding='utf-8') as ...

  3. CSS预处理器之less和sass

    CSS预处理器 1.        基于CSS的另一种语言 2.        通过工具编译成CSS 3.        添加了很多CSS不具备的特性 4.        能提升CSS文件的组织方式 ...

  4. Kubernetes服务发现入门:如何高效管理服务?

    愈发复杂的应用程序正在依靠微服务来保持可扩展性和提升效率.Kubernetes为微服务提供了完美的环境,并能够让其与Kubernetes的工具组件和功能兼容.当应用程序的每个部分放置在一个容器中,整个 ...

  5. SoC的软件开发流程,主要包含一些Linux下的操作命令

    该笔记主要记录SoC的软件开发流程,主要包含一些Linux下的操作命令 1. 编写design file .c .h 2. 编写makefile    可执行文件名,交叉编译环境,compile fl ...

  6. pip和conda添加国内清华镜像源(亲测有效)

    文章目录 pip和conda 添加国内清华镜像 1. pip源更改: 2. conda源更改: pip和conda 添加国内清华镜像 python模块安装,使用国内源可以提高下载速度. 1. pip源 ...

  7. [ASP.NET Core 3框架揭秘] 跨平台开发体验: Linux

    如果想体验Linux环境下开发.NET Core应用,我们有多种选择.一种就是在一台物理机上安装原生的Linux,我们可以根据自身的喜好选择某种Linux Distribution,目前来说像RHEL ...

  8. CentOS7 下nginx与PHP的安装与配置

    下载Nginx 1.在服务器上新建文件夹  /home/soft/ ; 2.cd /home/soft/    =>    执行命令下载Nginx    wget http://nginx.or ...

  9. Linux上用IP转发使内部网络连接互联网

    IP转发的概念: 使 Linux 机器像路由器一样将数据从一个网络发送到另一个网络.所以,它能作为一个路由器或者代理服务器,实现将一个连接的互联网或者网络连接共享给多个客户端机器. 1. 启用 IPv ...

  10. WinCC的电子签名与审计追踪

    如何写入审计追踪记录 用脚本向Audit中添加记录有两种方法,一种方法是用InserAuditEntryNew函数写入,另一种方法是生成属于“操作员输入消息”类型的报警消息,该报警消息会记录到Audi ...