Trie树


概念

  • 多叉树,节点为字符串中的单个字符。
  • Trie 树的本质,就是利用字符串之间的公共前缀,将重复的前缀合并在一起。
  • 将多个字符串按字符拆分插入Trie树,用于字符串查找,关键词提示等

  • 举例:我们有 6 个字符串,它们分别是:how,hi,her,hello,so,see。我们希望在里面多次查找某个字符串是否存在,可组成如下Trie树:

实现

  • 两个操作:将字符串集合构造成 Trie 树;在Trie树中查询一个字符串
  • 假设我们的字符串中只有从 a 到 z 这 26 个小写字母,我们在数组中下标为 0 的位置,存储指向子节点 a 的指针,下标为 1 的位置存储指向子节点 b 的指针,以此类推,下标为 25 的位置,存储的是指向的子节点 z 的指针。如果某个字符的子节点不存在,我们就在对应的下标的位置存储 null。

  • 节点定义
class TrieNode {
char data;
TrieNode children[26];
}
  • 构造和查询操作实现
public class Trie {
private TrieNode root = new TrieNode('/'); // 存储无意义字符 // 往Trie树中插入一个字符串
public void insert(char[] text) {
TrieNode p = root;
for (int i = 0; i < text.length; ++i) {
int index = text[i] - 'a';
if (p.children[index] == null) {
TrieNode newNode = new TrieNode(text[i]);
p.children[index] = newNode;
}
p = p.children[index];
}
p.isEndingChar = true;
} // 在Trie树中查找一个字符串
public boolean find(char[] pattern) {
TrieNode p = root;
for (int i = 0; i < pattern.length; ++i) {
int index = pattern[i] - 'a';
if (p.children[index] == null) {
return false; // 不存在pattern
}
p = p.children[index];
}
if (p.isEndingChar == false) return false; // 不能完全匹配,只是前缀
else return true; // 找到pattern
} public class TrieNode {
public char data;
public TrieNode[] children = new TrieNode[26];
public boolean isEndingChar = false;
public TrieNode(char data) {
this.data = data;
}
}
}
  • 时间复杂度:O(k), k为查询字符串的长度

Tire树很耗内存

  • 每个节点需存储所有可能字符个数大小的节点数组,在包括大小写字母,数字,并且还有中文时,这个数组会很大。
  • 优化方法
    • 每个节点中的数组换成其他数据结构,来存储一个节点的子节点指针。选择有很多,比如有序数组、跳表、散列表、红黑树等。

      • 结构:假设我们用有序数组,数组中的指针按照所指向的子节点中的字符的大小顺序排列。
      • 查询:查询的时候,我们可以通过二分查找的方法,快速查找到某个字符应该匹配的子节点的指针。
      • 插入:在往 Trie 树中插入一个字符串的时候,我们为了维护数组中数据的有序性,就会稍微慢了点。
    • 缩点优化:对只有一个子节点的节点,而且此节点不是一个串的结束节点,可以将此节点与子节点合并。这样可以节省空间,但却增加了编码难度。

Trie 树与散列表、红黑树的比较

  • 字符串中包含的字符集不能太大
  • 要求字符串的前缀重合比较多,不然空间消耗会变大很多
  • 要用 Trie 树解决问题,需要自己实现,红黑树和散列表有语言自己的成熟实现。
  • 数据是指针串起来的,内存不连续,对缓存不友好。

扩展应用

  • 比如输入法自动补全功能、IDE 代码编辑器自动补全功能、浏览器网址输入的自动补全功能等等。

数据结构与算法简记--Trie树的更多相关文章

  1. 13-看图理解数据结构与算法系列(Trie树)

    Trie树 Trie树,是一种搜索树,也称字典树或单词查找树,此外也称前缀树,因为某节点的后代存在共同的前缀.它的key都为字符串,能做到高效查询和插入,时间复杂度为O(k),k为字符串长度,缺点是如 ...

  2. 【数据结构与算法】Trie(前缀树)模板和例题

    Trie 树的模板 Trie 树的简介 Trie树,又称字典树,单词查找树或者前缀树,是一种用于快速检索的多叉树结构,如英文字母的字典树是一个26叉树,数字的字典树是一个10叉树.他的核心思想是空间换 ...

  3. [算法]从Trie树(字典树)谈到后缀树

    我是好文章的搬运工,原文来自博客园,博主July_,地址:http://www.cnblogs.com/v-July-v/archive/2011/10/22/2316412.html 从Trie树( ...

  4. 19-看图理解数据结构与算法系列(Radix树)

    Radix树 Radix树,即基数树,也称压缩前缀树,是一种提供key-value存储查找的数据结构.与Trie不同的是,它对Trie树进行了空间优化,只有一个子节点的中间节点将被压缩.同样的,Rad ...

  5. Java数据结构和算法(七)--AVL树

    在上篇博客中,学习了二分搜索树:Java数据结构和算法(六)--二叉树,但是二分搜索树本身存在一个问题: 如果现在插入的数据为1,2,3,4,5,6,这样有序的数据,或者是逆序 这种情况下的二分搜索树 ...

  6. 算法复习——trie树(poj2001)

    题目: 题目描述 给出 n 个单词(1<=n<=1000),求出每个单词的非公共前缀,如果没有,则输出自己. 输入格式 输入 N 个单词,每行一个,每个单词都是由 1-20 个小写字母构成 ...

  7. 数据结构与算法17—B树(B、B+、B*)

    B树 B-树,就是B树,B树的原英文名是B-tree,所以很多翻译为B-树,就会很多人误以为B-树是一种树.B树是另外一种树.其实,B-tree就是B树. B-树的定义 B树(B-tree)是一种树状 ...

  8. Java数据结构与算法(20) - ch08树

    树的主要算法有插入,查找,显示,遍历,删除,其中显示和删除略微复杂. package chap08.tree; import java.io.BufferedReader; import java.i ...

  9. 【数据结构与算法】002—树与二叉树(Python)

    概念 树 树是一类重要的非线性数据结构,是以分支关系定义的层次结构 定义: 树(tree)是n(n>0)个结点的有限集T,其中: 有且仅有一个特定的结点,称为树的根(root) 当n>1时 ...

随机推荐

  1. python类与对象

    1.  class命名规范:首字母大写,驼峰命名法 2.  class 里面函数括号里面带(self)说明这是一个实例,调用实例方法需要用实例调用 class Teacher: def  test_1 ...

  2. 转 使用Python的logging.config.fileConfig配置日志

    Python的logging.config.fileConfig方式配置日志,通过解析conf配置文件实现.文件 logglogging.conf 配置如下: [loggers]keys=root,f ...

  3. exsi 回收虚拟机磁盘

    用客户端登陆服务端,用下面命令停止虚拟机机器 esxcli vm process list    用如下命令关闭一台虚拟机: esxcli vm process kill --type=[soft,h ...

  4. Robot Framework 执行结果无法查看(tomcat部署)

    打开jenkins系统管理-命令行执行: System.setProperty("hudson.model.DirectoryBrowserSupport.CSP","& ...

  5. Redis缓存击穿、缓存穿透、缓存雪崩

    文章原创于公众号:程序猿周先森.本平台不定时更新,喜欢我的文章,欢迎关注我的微信公众号. 上篇文章谈到了Redis分布式锁,实际上就是为了解释为什么做缓存采用Redis而不使用map/guava.缓存 ...

  6. Shell02---变量

    Shell02---变量 1. shell变量概述 1. 什么是变量 变量是Shell传递数据的一种方法,简单理解:用一个固定的字符串去表示不固定的内容,便于后续引用. 2.变量命令规范 变量定义时名 ...

  7. mysql---级联更新和删除操作

    我们通常有这样的需求:删除表Table 1中记录,需要同时删除其它表中与Table 1有关的若干记录. 对于这种,我们有两种解决方法: 一,使用innodb表的外键约束 ALTER TABLE `sc ...

  8. Android开发中怎样用多进程、用多进程的好处、多进程的缺陷、解决方法(转)

    转自:http://blog.csdn.net/spencer_hale/article/details/54968092 1.怎样用多进程 Android多进程概念:一般情况下,一个应用程序就是一个 ...

  9. spring Data solr依赖文件 和xml配置文件

    <dependencies>        <dependency>            <groupId>org.springframework.data< ...

  10. PIC16F877A的TIME0学习

    计算溢出时间根据晶振频率4Mhz,TMR0=6,PSA2~PSA0 = 1:4. 因为好像外部晶振在给PIC的时候多分了一次1:4.所以PSA2~PSA0取1:4刚好 数完250次的时间=(1/4Mh ...