数据结构与算法简记--Trie树
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树的更多相关文章
- 13-看图理解数据结构与算法系列(Trie树)
Trie树 Trie树,是一种搜索树,也称字典树或单词查找树,此外也称前缀树,因为某节点的后代存在共同的前缀.它的key都为字符串,能做到高效查询和插入,时间复杂度为O(k),k为字符串长度,缺点是如 ...
- 【数据结构与算法】Trie(前缀树)模板和例题
Trie 树的模板 Trie 树的简介 Trie树,又称字典树,单词查找树或者前缀树,是一种用于快速检索的多叉树结构,如英文字母的字典树是一个26叉树,数字的字典树是一个10叉树.他的核心思想是空间换 ...
- [算法]从Trie树(字典树)谈到后缀树
我是好文章的搬运工,原文来自博客园,博主July_,地址:http://www.cnblogs.com/v-July-v/archive/2011/10/22/2316412.html 从Trie树( ...
- 19-看图理解数据结构与算法系列(Radix树)
Radix树 Radix树,即基数树,也称压缩前缀树,是一种提供key-value存储查找的数据结构.与Trie不同的是,它对Trie树进行了空间优化,只有一个子节点的中间节点将被压缩.同样的,Rad ...
- Java数据结构和算法(七)--AVL树
在上篇博客中,学习了二分搜索树:Java数据结构和算法(六)--二叉树,但是二分搜索树本身存在一个问题: 如果现在插入的数据为1,2,3,4,5,6,这样有序的数据,或者是逆序 这种情况下的二分搜索树 ...
- 算法复习——trie树(poj2001)
题目: 题目描述 给出 n 个单词(1<=n<=1000),求出每个单词的非公共前缀,如果没有,则输出自己. 输入格式 输入 N 个单词,每行一个,每个单词都是由 1-20 个小写字母构成 ...
- 数据结构与算法17—B树(B、B+、B*)
B树 B-树,就是B树,B树的原英文名是B-tree,所以很多翻译为B-树,就会很多人误以为B-树是一种树.B树是另外一种树.其实,B-tree就是B树. B-树的定义 B树(B-tree)是一种树状 ...
- Java数据结构与算法(20) - ch08树
树的主要算法有插入,查找,显示,遍历,删除,其中显示和删除略微复杂. package chap08.tree; import java.io.BufferedReader; import java.i ...
- 【数据结构与算法】002—树与二叉树(Python)
概念 树 树是一类重要的非线性数据结构,是以分支关系定义的层次结构 定义: 树(tree)是n(n>0)个结点的有限集T,其中: 有且仅有一个特定的结点,称为树的根(root) 当n>1时 ...
随机推荐
- Python3函数中特殊形参的使用:*、*args、**kwargs
Python3函数中特殊形参的使用:*.*args.**kwargs ==用法1:不定长参数== 当函数需要的参数数量不确定的时候,可以使用*args 和 **kwargs , 所有的位置参数保存在* ...
- MySQL-mysql_config_editor安全登录工具
mysql_config_editor出现在mysql5.6.6以后的版本,可以给指定的连接和密码生成一个加密文件.mylogin.cnf,默认位于当前用户家目录下.通过该文件可以使用mysql.my ...
- 什么是Spring Boot?
什么是Spring Boot? Spring Boot是Spring开源组织下的子项目,是Spring组件一站式解决方案,主要是简化了使用Spring的难度,简省了繁重的配置,提供了各种启动器,开发者 ...
- UVALive 4992 Jungle Outpost(半平面交判存)
Jungle Outpost Time limit: 15.000 seconds Description There is a military base lost deep in the jung ...
- 【笔记目录2】ASP.NET Core分布式项目实战
当前标签: ASP.NET Core分布式项目实战 共2页: 上一页 1 2 11.ClientCredential模式总结 GASA 2019-03-11 12:59 阅读:26 评论:0 10. ...
- MyEclipse更换工作空间报错自动退出
2.解决方法 后来找到一种方法,解决了我的问题,即找到图二中报错的那个jar包,我的是com.genuitec.eclipse.core_14.0.0.me201602080330.jar,然后将其文 ...
- SQL查询连续年份
有这样一个问题,给出一个表格记录了夺冠球队的名称和年份,我们要做的就是写出一条SQL语句,查询再次期间连续夺冠的有哪些,起止时间是什么 下边是代码 create table #t(TEAM vaarc ...
- 西里尔字 俄语 - Cyrillic
https://zh.wikipedia.org/wiki/%E8%A5%BF%E9%87%8C%E5%B0%94%E5%AD%97%E6%AF%8D 其他编码[编辑] 其他适用西里尔字母的字符编码系 ...
- Codeforces 364E 分治
题意:给你一个01矩阵,问此矩阵有多少个和恰好为k的子矩形. 思路:分治,对于当前矩形,用一条中线把矩形分成两半,分治之后计算跨过中线的矩形个数.更具体的来说(假设划了一条水平中线),我们枚举矩形左右 ...
- CNN基础三:预训练模型的微调
上一节中,我们利用了预训练的VGG网络卷积基,来简单的提取了图像的特征,并用这些特征作为输入,训练了一个小分类器. 这种方法好处在于简单粗暴,特征提取部分的卷积基不需要训练.但缺点在于,一是别人的模型 ...