数据结构与算法专题——第十二题 Trie树

https://mp.weixin.qq.com/s/nndr2AcECuUatXrxd3MgCg

今天来聊一聊Trie树,Trie树的名字有很多,比如字典树,前缀树等等。

一:概念
下面有and,as,at,cn,com这几个关键词,构建成 trie 树如下。

从上面图中,应该可以或多或少的发现一些好玩的特性。

  • 根节点不包含字符,除根节点外的每一个子节点都包含一个字符。
  • 从根节点到某一节点,路径上经过的字符连接起来,就是该节点对应的字符串。
  • 每个单词的公共前缀作为一个字符节点保存。

二:使用范围

既然学Trie树,肯定要知道这玩意是用来干嘛的?

1. 词频统计。

可能有人要说了,词频统计简单啊,一个hash或者一个堆就可以打完收工,但问题来了,如果内存有限呢?还能这么玩吗?这种限制级条件下就可以用trie树来压缩下空间,因为公共前缀都是用一个节点保存的。

2. 前缀匹配

就拿上面的图来说吧,如果我想获取所有以 "a" 开头的字符串,从图中可以很明显的看到是:and,as,at,如果不用trie树,你该怎么做呢?很显然朴素的做法时间复杂度为O(N2) ,用Trie树就不一样了,它可以做到h,h为你检索单词的长度,可以说这是秒杀的效果。

举个例子:现有一个编号为1的字符串”and“,怎样插入到trie树中呢?采用动态规划的思想,将编号”1“计入到每个途径的节点中,那么以后我们要找”a“,”an“,”and"为前缀的字符串的编号将会轻而易举。

三:实际操作

到现在为止,我想大家已经对trie树有了大概的掌握,下面看看如何来实现。

1:定义trie树节点

为了方便,我也采用纯英文字母,大家都知道字母有26个,所以构建的trie树就是一个26叉树,每个节点包含26个子节点,实现代码如下:


/// <summary>
/// Trie树节点
/// </summary>
public class TrieNode
{
/// <summary>
/// 26个字符,也就是26叉树
/// </summary>
public TrieNode[] childNodes; /// <summary>
/// 词频统计
/// </summary>
public int freq; /// <summary>
/// 记录该节点的字符
/// </summary>
public char nodeChar; /// <summary>
/// 插入记录时的编码id
/// </summary>
public HashSet<int> hashSet = new HashSet<int>(); /// <summary>
/// 初始化
/// </summary>
public TrieNode()
{
childNodes = new TrieNode[26];
freq = 0;
}
}

2: 添加操作

从上面图中,应该可以或多或少的发现一些好玩的特性。

  • 根节点不包含字符,除根节点外的每一个子节点都包含一个字符。
  • 从根节点到某一节点,路径上经过的字符连接起来,就是该节点对应的字符串。
  • 每个单词的公共前缀作为一个字符节点保存。

二:使用范围

既然学Trie树,肯定要知道这玩意是用来干嘛的?

1. 词频统计。

可能有人要说了,词频统计简单啊,一个hash或者一个堆就可以打完收工,但问题来了,如果内存有限呢?还能这么玩吗?这种限制级条件下就可以用trie树来压缩下空间,因为公共前缀都是用一个节点保存的。

2. 前缀匹配

就拿上面的图来说吧,如果我想获取所有以 "a" 开头的字符串,从图中可以很明显的看到是:and,as,at,如果不用trie树,你该怎么做呢?很显然朴素的做法时间复杂度为O(N2) ,用Trie树就不一样了,它可以做到h,h为你检索单词的长度,可以说这是秒杀的效果。

举个例子:现有一个编号为1的字符串”and“,怎样插入到trie树中呢?采用动态规划的思想,将编号”1“计入到每个途径的节点中,那么以后我们要找”a“,”an“,”and"为前缀的字符串的编号将会轻而易举。

最新文章

  1. WPF显示Html
  2. Xcode自定义Eclipse中常用的快捷键
  3. 利用WCF技术降低系统之间的耦合度
  4. 《数据结构与算法JavaScript描述》
  5. html的input输入框边框
  6. 10 Best TV Series Based On Hacking And Technology
  7. jQuery中利用JSONP解决AJAX跨域问题
  8. 5步解决移动设备上的300ms点击延迟
  9. 【转】phpmyadmin万能密码漏洞
  10. printf 输出格式
  11. uva 11991 - Easy Problem from Rujia Liu?(STL)
  12. Android网络开发之OkHttp--基本用法POST
  13. Memcached源码分析之assoc.c
  14. Material Theme 文件名的标签(tab)被大写了
  15. redis从入门到
  16. Java中 float、double使用注意问题
  17. SLAM学习--开源测试数据集合
  18. Linux root目录下.gvfs问题处理
  19. redis学习-散列表常用命令(hash)
  20. C语言 &#183; 2n皇后问题

热门文章

  1. 【磁盘/文件系统】第五篇:CentOS7.x__btrfs文件系统详解
  2. springboot 中yml配置
  3. 感知机:Perceptron Learning Algorithm
  4. 简述java多态
  5. 高性能MySQL学习总结二----常见数据类型选择及优化
  6. 【Linux】使用笔记
  7. Kubernetes官方java客户端之二:序列化和反序列化问题
  8. 图解HTTP权威指南(五) | HTTP缓存
  9. 初识分布式图数据库 Nebula Graph 2.0 Query Engine
  10. 十、scala、spark集群搭建