`

Trie树和其它数据结构的比较

阅读更多

Trie树和其它数据结构的比较

Trie树,又叫做前缀树或者是字典树,是一种有序的树。从空字符串的根开始,往下遍历到某个节点,确定了对应的字符串,也就是说,任意一个节点的所有子孙都具备相同的前缀。每一棵Trie树都可以被看做是一个简单版的确定有限状态的自动机(DFA,deterministic finite automaton),也就是说,对于一个任意给定的属于该自动机的状态(①)和一个属于该自动机字母表的字符(②),都可以根据给定的转移函数(③)转到下一个状态去。其中:

  • ① 对于Trie树中的每一个节点都确定了一个自动机的状态;
  • ② 给定一个属于该自动机字母表的字符,在图中可以看到根据不同的字符形成的分支;
  • ③ 从当前节点进入下一层次节点的过程经过状态转移函数得出。

一个非常常见的应用就是搜索提示,在搜索框中输入搜索信息的前缀,如“乌鲁”,提示“乌鲁木齐”;再有就是输入法的联想功能,也是一样的道理。

和二叉搜索树(binary search tree)相比

二叉搜索树又叫做二叉排序树,它满足:

  • 任意节点如果左子树不为空,左子树所有节点的值都小于根节点的值;
  • 任意节点如果右子树不为空,右子树所有节点的值都大于根节点的值;
  • 左右子树也都是二叉搜索树;
  • 所有节点的值都不相同。

其实二叉搜索树的优势已经在与查找、插入的时间复杂度上了,通常只有O(log n),很多集合都是通过它来实现的。在进行插入的时候,实质上是给树添加新的叶子节点,避免了节点移动,搜索、插入和删除的复杂度等于树的高度,属于O(log n),最坏情况下整棵树所有的节点都只有一个子节点,完全变成一个线性表,复杂度是O(n)。

Trie树在最坏情况下查找要快过二叉搜索树,如果搜索字符串长度用m来表示的话,它只有O(m),通常情况(树的节点个数要远大于搜索字符串的长度)下要远小于O(n)。

我们给Trie树举例子都是拿字符串举例的,其实它本身对key的适宜性是有严格要求的,如果key是浮点数的话,就可能导致整个Trie树巨长无比,节点可读性也非常差,这种情况下是不适宜用Trie树来保存数据的;而二叉搜索树就不存在这个问题。

和Hash表相比

考虑一下Hash表键冲突的问题。Hash表通常我们说它的复杂度是O(1),其实严格说起来这是接近完美的Hash表的复杂度,另外还需要考虑到hash函数本身需要遍历搜索字符串,复杂度是O(m)。在不同键被映射到“同一个位置”(考虑closed hashing,这“同一个位置”可以由一个普通链表来取代)的时候,需要进行查找的复杂度取决于这“同一个位置”下节点的数目,因此,在最坏情况下,Hash表也是可以成为一张单向链表的(对于Hash冲突问题,请阅读《Hash Collision DoS问题》)。

Trie树可以比较方便地按照key的字母序来排序(整棵树先序遍历一次就好了),这是绝大多数Hash表是不同的(Hash表一般对于不同的key来说是无序的)。

在较理想的情况下,Hash表可以以O(1)的速度迅速命中目标,如果这张表非常大,需要放到磁盘上的话,Hash表的查找访问在理想情况下只需要一次即可;但是Trie树访问磁盘的数目需要等于节点深度。

很多时候Trie树比Hash表需要更多的空间,我们考虑这种一个节点存放一个字符的情况的话,在保存一个字符串的时候,没有办法把它保存成一个单独的块。Trie树的节点压缩可以明显缓解这个问题,后面会讲到。

和后缀树相比

Trie树和其它数据结构的比较

后缀树压缩存储了一段文本的所有可能的后缀,如给定单词“banana”,可能的后缀包括:a、na、ana、nana、anana、banana这几种,上图已经将所有可能全部放在树中表示出来了,“$”表示一个后缀的结束,同时,还做到了尽量的分支压缩(分支压缩的说明在下文中也有提及)。对于给定长度为n的文本构造后缀树,它的定义要点包括:

  • 树有n个叶子节点,分别从1到n来命名;
  • 除了根节点,所有的非叶子节点至少有两个孩子;
  • 每一条边代表原文本的一个非空子串;
  • 不存在两条边以同一个字符开串标记且以同一个字符结尾;
  • 在从根节点到叶子 i 的路径上,连接所有字符串标记形成的字符串,都表示了一个原文本的后缀子串。

 

构造后缀树根据文本长度需要消耗线性的时间。和Trie树相比,后缀树做到了用空间换时间,考虑全文搜索的情况,后缀树把所有可能的后缀子串都索引化了,就避免了Trie树深度遍历整棵树的过程。在算法题中许多关于“前缀子串问题上,我们经常使用Trie树来求解,但是如果问题仅仅涉及“子串”,往往选用后缀树;另外,还有一个重要的使用在文本压缩算法上,通过后缀树可以找到重复率高的文本,实现重复文本抽取,放到字典映射表中去。

Trie树的改进

1. 按位Trie树(Bitwise Trie):原理上和普通Trie树差不多,只不过普通Trie树存储的最小单位是字符,但是Bitwise Trie存放的是位而已。位数据的存取由CPU指令一次直接实现,对于二进制数据,它理论上要比普通Trie树快。

2. 节点压缩。

  • ① 分支压缩:对于稳定的Trie树,基本上都是查找和读取操作,完全可以把一些分支进行压缩。例如,前图中最右侧分支的inn可以直接压缩成一个节点“inn”,而不需要作为一棵常规的子树存在。Radix树就是根据这个原理来解决Trie树过深问题的。
  • ② 节点映射表:这种方式也是在Trie树的节点可能已经几乎完全确定的情况下采用的,针对Trie树中节点的每一个状态,如果状态总数重复很多的话,通过一个元素为数字的多维数组(比如Triple Array Trie)来表示,这样存储Trie树本身的空间开销会小一些,虽说引入了一张额外的映射表。

文章系本人原创,转载请保持完整性并注明出自《四火的唠叨》

0
1
分享到:
评论

相关推荐

    NYOJ.290.DictionaryTree.zip_trie树c_字典树_高级数据结构

    字典树,也被称为Trie树或前缀树,是一种高效的数据结构,尤其适用于字符串相关的查找和插入操作。在计算机科学领域,它被广泛应用在字典、搜索引擎、自动补全功能以及IP路由等方面。Trie树的核心优势在于其能够通过...

    Trie树 结构描述 实现方法 用法

    Trie树,也被称为前缀树或字典树,是一种数据结构,主要用于高效地存储和检索字符串。在Trie树中,每个节点代表一个字符串的前缀,而从根节点到某个节点的路径上的边代表了这个节点所代表的字符串。这种结构特别适合...

    Trie树入门,很容易上手

    相对来说,Trie树是一种比较简单的数据结构。理解起来比较简单,但是简单的东西也得付出代价。故Trie树也有它的缺点,Trie树的内存消耗非常大。 Trie树的基本性质可以归纳为: 1. 根节点不包含字符,除根节点外每...

    数据结构实验报告-----trie树

    **数据结构实验报告——Trie树** Trie树,又称为前缀树或字典树,是一种用于存储字符串的有效数据结构。它通过将字符串的字符分解并存储在树的节点中,来实现高效的字符串查找、插入和删除操作。在Trie树中,每个...

    IT笔试面试--Trie树前缀树常考题目及解析

    ### IT笔试面试--Trie树...Trie树是一种非常重要的数据结构,在信息检索、字符串匹配等领域有着广泛的应用,同时也是很多算法和复杂数据结构的基础。掌握Trie树不仅有助于解决实际问题,也能提升个人在IT领域的竞争力。

    数据结构课设Trie树

    在这个课设中,`file.cpp`很可能是实现Trie树数据结构及其操作的源代码文件。可能包括插入单词、删除单词、查找单词、显示所有以特定前缀开头的单词等功能。C++是实现这类算法的常用编程语言,它提供了丰富的控制...

    Trie 树实现的源码

    Trie树,也称为前缀树或字典树,是一种用于存储字符串数据结构。它利用字符串间的公共前缀来减少所需的存储空间,使得查找字符串更加高效。Trie树在很多应用中都有广泛的应用,如拼写检查、自动补全功能等。 #### ...

    C++/C Trie树算法

    用C实现的数据结构Trie树算法 实验的函数的trie树的插入 搜索和删除

    基于Trie树模仿谷歌百度搜索框提示

    综上所述,通过Trie树数据结构和Java编程,我们可以构建一个高效的搜索提示系统,模拟谷歌和百度的搜索体验。这涉及到Trie树的插入和查找操作,以及与用户界面交互的逻辑处理。在实际开发中,我们还需要关注性能优化...

    从trie树谈到后缀树

    Trie树,又称为字典树,是一种特殊的树形数据结构,主要用于高效地存储和检索字符串。它的设计目的是通过利用字符串的公共前缀来减少字符串比较的次数,从而提高查询效率。Trie树的核心特点是: 1. 根节点不包含...

    HASH(Trie)-.rar_HashTree.h_TRIE_hash树_trie树_字典树

    **哈希 Trie 树(HashTrie)与字典树(Trie树)详解** 哈希 Trie 树,也称为 HashTrie 或者是哈希化的 Trie 树,是一种结合了哈希表和 Trie 数据结构特点的数据结构。它在 Trie 树的基础上引入了哈希函数,提高了...

    Acm Trie树

    **Trie树**,又称为**字典树**或**前缀树**,是一种用于高效存储和检索字符串的树形数据结构。它通过利用字符串之间的公共前缀来减少查询时间,从而提高搜索效率。在诸如文本编辑器、搜索引擎、自动补全等功能中非常...

    数据结构trie

    算法实现,C++实现trie树,完成该算法的实现,运用运用

    DoubleArrayTrie(双数组Trie树)

    总结,DoubleArrayTrie是一种高效的字符串查找数据结构,它的设计和实现结合了Trie树的特性并进行了优化,适用于需要快速处理大量字符串的场景。在实际应用中,了解和掌握DAT的原理和使用方法,对于提升字符串处理的...

    Trie树(字典数\字符树)基本原理

    Trie 树,也称为字典树,是一种树形数据结构,用于高效存储和查询字符串。其核心思想是空间换时间,即通过占用更多的存储空间来换取查询速度的提高。 Trie 树的基本结构是一个节点数组,每个节点对应一个字符,从根...

    基于双数组Trie_树中文分词研究

    Trie树是一种用于高效存储和检索字符串数据的数据结构,特别适用于构建词典。对于给定的字符串α1, α2, …, αn,在Trie树中搜索最多只需要经过n次匹配即可完成一次查找,这使得它成为中文匹配分词算法中词典的一种...

    ACM Trie树 模板 字典树

    ACM Trie树 模板,字典树模板,数据结构

    Trie树题解1

    Trie树,又称字典树或前缀树,是一种用于高效存储和检索字符串的数据结构。它的主要特点是能够快速查找一个字符串是否是另一个字符串的前缀,这对于处理大量字符串的问题非常有用。在题目描述中提到的POJ1056、POJ...

    实现trie树的C/C++模板

    在计算机科学领域,Trie树(又称前缀树或字典树)是一种用于存储具有共同前缀的字符串的高效数据结构。它广泛应用于各种场景,如自动补全、拼写检查以及IP路由表等。本文将详细介绍如何在C/C++中实现一个基本的Trie...

Global site tag (gtag.js) - Google Analytics