数据结构08——Trie
一、什么是Trie?
Trie树,一般被称为字典树、前缀树等等,Trie是一种多叉树,这个和二分搜索树、堆、线段树这些数据结构不一样,因为这些都是二叉树。,Trie树除了是一种多叉树,它是一种哈希树的变种。因此Trie典型作用,是应用于统计和排序大量的字符串,所以经常被搜索引擎系统用于文本词频统计。它的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高。
Trie查询每个条目的时间复杂度和字典中一共有多少条目无关,其时间复杂度为O(w),这里的w乃是查询字单词的长度,二大多数单词的长度是小于10的。因此Trie核心思想是空间换时间,利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。
对于Trie二样,它有3个基本性质:
1. 根节点不包含字符,除根节点外每一个节点都只包含一个字符。
2. 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。
3. 每个节点的所有子节点包含的字符都不相同。
二、Trie的构建
1.Trie的创建
package com.zfy.trie; import java.util.TreeMap; /*
* 这里的Trie是基于java的内部类TreeMap
* */
public class Trie { private class Node { //用来描述当我梦幻访问到当前的Node时,是否就已经找到了一个单词
public boolean isWord;
//对于每一个节点要有向下一个节点的映射,因为Trie对于每一个节点向下指向多少个节点是不定的,所以这样的映射是从Character一直到Node这样的一个映射,这里设计为Character,但这仅仅是一种假设,因为这里仅仅是限制于英文的数据类型
public TreeMap<Character, Node> next; public Node(boolean isWord){
this.isWord = isWord;
next = new TreeMap<>();
} public Node(){
this(false);
}
} private Node root;//Trie的根节点
private int size;//Trie中的档次数量 //Trie的构造函数
public Trie(){
root = new Node();
size = 0;
} //获得Trie中存储的单词数量
public int getSize(){
return size;
} }
2.向Trie中添加数据
// 向Trie中添加一个新的单词word
public void add(String word) { Node cur = root;
for (int i = 0; i < word.length(); i++) {
char c = word.charAt(i);
// 检查cur是否已经有指向c这个字符相应的节点,如果没有才会新创建一个节点
if (cur.next.get(c) == null) {
cur.next.put(c, new Node());
}
cur = cur.next.get(c);
} // 判断cur是否已经在Trie中了,如果不在,才设置isWord为true
if (!cur.isWord) {
cur.isWord = true;
size++;
}
}
3.Trie字典树的查询和前缀查询
// 查询单词word是否在Trie中
public boolean contains(String word) { Node cur = root;
for (int i = 0; i < word.length(); i++) {
char c = word.charAt(i);
if (cur.next.get(c) == null) {
return false;
}
cur = cur.next.get(c);
}
return cur.isWord;
} // 查询是否在Trie中有单词以prefix为前缀
public boolean isPrefix(String prefix) { Node cur = root;
for (int i = 0; i < prefix.length(); i++) {
char c = prefix.charAt(i);
if (cur.next.get(c) == null)
return false;
cur = cur.next.get(c);
} return true;
}
4.完整代码
package com.zfy.trie; import java.util.TreeMap; /*
* 这里的Trie是基于java的内部类TreeMap
* */
public class Trie { private class Node { // 用来描述当我梦幻访问到当前的Node时,是否就已经找到了一个单词
public boolean isWord;
// 对于每一个节点要有向下一个节点的映射,因为Trie对于每一个节点向下指向多少个节点是不定的,所以这样的映射是从Character一直到Node这样的一个映射,这里设计为Character,但这仅仅是一种假设,因为这里仅仅是限制于英文的数据类型
public TreeMap<Character, Node> next; public Node(boolean isWord) {
this.isWord = isWord;
next = new TreeMap<>();
} public Node() {
this(false);
}
} private Node root;// Trie的根节点
private int size;// Trie中的档次数量 // Trie的构造函数
public Trie() {
root = new Node();
size = 0;
} // 获得Trie中存储的单词数量
public int getSize() {
return size;
} // 向Trie中添加一个新的单词word
public void add(String word) { Node cur = root;
for (int i = 0; i < word.length(); i++) {
char c = word.charAt(i);
// 检查cur是否已经有指向c这个字符相应的节点,如果没有才会新创建一个节点
if (cur.next.get(c) == null) {
cur.next.put(c, new Node());
}
cur = cur.next.get(c);
} // 判断cur是否已经在Trie中了,如果不在,才设置isWord为true
if (!cur.isWord) {
cur.isWord = true;
size++;
}
} // 查询单词word是否在Trie中
public boolean contains(String word) { Node cur = root;
for (int i = 0; i < word.length(); i++) {
char c = word.charAt(i);
if (cur.next.get(c) == null) {
return false;
}
cur = cur.next.get(c);
}
return cur.isWord;
} // 查询是否在Trie中有单词以prefix为前缀
public boolean isPrefix(String prefix) { Node cur = root;
for (int i = 0; i < prefix.length(); i++) {
char c = prefix.charAt(i);
if (cur.next.get(c) == null)
return false;
cur = cur.next.get(c);
} return true;
}
}
结束语:合抱之木,生于毫末;九层之台,起于累土;千里之行,始于足下。
参考:bobobo老师的玩转数据结构
版权声明:尊重博主原创文章,转载请注明出处 https://www.cnblogs.com/hsdy
数据结构08——Trie的更多相关文章
- [转]数据结构之Trie树
1. 概述 Trie树,又称字典树,单词查找树或者前缀树,是一种用于快速检索的多叉树结构,如英文字母的字典树是一个26叉树,数字的字典树是一个10叉树. Trie一词来自retrieve,发音为/tr ...
- 数据结构之Trie树
1. 概述 Trie树,又称字典树,单词查找树或者前缀树,是一种用于快速检索的多叉树结构,如英文字母的字典树是一个26叉树,数字的字典树是一个10叉树. Trie一词来自retrieve,发音为/tr ...
- 【数据结构】Trie树
数据结构--Trie树 概念 Trie树,又称字典树.前缀树,是一种树形结构,是一种哈希树的变种.典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计 ...
- 数据结构(trie,启发式合并):HDU 5841 Alice and Bob
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABJEAAAE6CAIAAAApz1RvAAAgAElEQVR4nO3d3css1b3g8fyTdbHJbD
- 用js来实现那些数据结构08(链表02-双向链表)
其实无论在任何语言中,一种数据结构往往会有很多的延伸和变种以应对不同场景的需要.其实前面我们所学过的栈和队列也是可以用链表来实现的.有兴趣的小伙伴可以自己尝试着去实现以下. 有点跑题了...,我们还是 ...
- 【经典数据结构】Trie
在计算机科学中,trie,又称前缀树或字典树,是一种有种树,用于保存关联数组,其中的键通常是字符串.与二叉查找树不同,键不是直接保存在节点中,而是由节点在树中的位置决定.一个节点的所有子孙都有相同的前 ...
- java数据结构-08队列
一.什么是队列 队列是一种特殊的线性表,只能在头尾两端进行操作,特点是先进先出:就像排队买票一样,先来的先买 二.接口设计 三.代码实现 可以使用动态数组.链表等实现:这里两种实现栈与双向链表 1. ...
- 数据结构《17》---- 自动补齐之《二》----Ternary Search Tree
一. 序言 上一篇文章中,给出了 trie 树的一个实现.可以看到,trie 树有一个巨大的弊病,内存占用过大. 本文给出另一种数据结构来解决上述问题---- Ternary Search Tree ...
- 字符串 --- KMP Eentend-Kmp 自动机 trie图 trie树 后缀树 后缀数组
涉及到字符串的问题,无外乎这样一些算法和数据结构:自动机 KMP算法 Extend-KMP 后缀树 后缀数组 trie树 trie图及其应用.当然这些都是比较高级的数据结构和算法,而这里面最常用和最熟 ...
随机推荐
- C#-XML-数据传输
http://www.cnblogs.com/fengxuehuanlin/p/5631664.html 关于xml是属于一个比较重要的东西,在平时开发的过程中,这块内容最主要的是要掌握XML内容的读 ...
- Scratch GUI
原文地址:https://github.com/LLK/scratch-gui/wiki/Getting-Started Getting Started Bryce Taylor edited t ...
- Visual Staudio 2015 打开指定文件,定位到指定文件目录下
Visual Staudio 2015 项目定位文件位置 每次使用的Visual Staudio 2015 写代码的时候总是打开了.cs文件或xaml文件时, 还要手动去找该 文件位置,每次都要翻好大 ...
- C# Array类的Sort()方法
Array类实现了数组中元素的冒泡排序.Sort()方法要求数组中的元素实现IComparable接口.如System.Int32 和System.String实现了IComparable接口,所以下 ...
- CAGradientLayer实现图片渐变透明效果
CAGradientLayer实现图片渐变透明效果 要实现的效果如下: 源码: // // RootViewController.m // CAGradientLayer // // Copyrigh ...
- 监控事件日志关键字规则(EventDescription)
新建规则--基于NT事件日志--自定义条件:EventDescription - 包含 - 关键字
- maven将依赖的包一起打包
把以下内容输入到pom中即可 <build> <plugins> <!-- 将项目的依赖包复制到 target/lib --> <plugin> < ...
- Redis 拒绝连接
1.本地防火墙是否关闭 2.服务器的防火墙是否关闭 检查方法: service iptables status 查看防火墙状态 service iptables s ...
- Entity Framework 指定架构无效 错误:1052
IIS发布网站:如果不发布放到IIS没有问题,发布后IIS部署 打开网站却提示指定架构无效 1052 找到很多解决的问题 1添加wenconfig 2.更改entity名的 其实我认为最简单的就是先找 ...
- MD5随机盐值生成法
public class Test3 { /** * 生成含有随机盐的密码 */ public static String generate(String password) { Random r = ...