数据结构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图及其应用.当然这些都是比较高级的数据结构和算法,而这里面最常用和最熟 ...
随机推荐
- .net core Web应用启动类
在ASP.NET Core中,Startup类为Web应用的入口类,用于配置Web服务的管道/过滤器以及Web应用所能用到的服务.在启动Web应用后,ASP.NET将在主库中查询名为Startup的类 ...
- PHPStorm/webstorm/PyCharm tips
phpstorm对于使用PHP开发web的人员来说,是一个非常不错的编辑开发IDE,以前用过sublime,但是相比于storm,sublime在浏览legacy代码,类代码编辑方面明显要逊色不少.同 ...
- rabbitmq集群配置
原文地址:http://www.360doc.com/content/14/0911/17/15077656_408713893.shtml 按照文章中的方式成功建立了两台机器的集群. 但文章中加入集 ...
- xss challenges平台学习
虽然在很早之前就接触过xss,有一段时间还就着一本书研究过,但是始终没有实感,掌握的也不够系统,所以现在借着这几个平台再学习一遍 首先来玩一玩xss challenge平台 第一关:http://xs ...
- CopyrightHelper—开源VS插件辅助插入版权注释
前言 有很多时候,我们在写代码的时候需要在代码文件头加上描述和版权信息等,如果使用代码项目模板又得为每种文件定模板,而已不方便,如果从某个地方复制过来,又嫌麻烦... 为了能解决这种懒人的需求,我开始 ...
- nginx+lvs+keepalived安装
安装nginx 配置文件和之前的一样 user nobody nobody; #定义Nginx运行的用户和用户组 worker_processes 4; #nginx进程数,建议设置为等于 ...
- Socket Tools的使用
1.启动工具 Socket Tools.exe , 分享:链接:http://pan.baidu.com/s/1dFiuEHz 密码:1sv9 2.在本地创建TCP Server,自动启动监听 3.在 ...
- Asp.net & Aspose.cells 导入
Workbook workBook = new Workbook(this.fuFile.FileContent); Aspose.Cells.Worksheet sheet = workBook.W ...
- 5、Web Service-整合CXF
1.工程准备 继续使用之前的服务端:https://www.cnblogs.com/Mrchengs/p/10562458.html 2.jar准备 前去apache官网下载响应的jar:http:/ ...
- linq查询语法和方法-簡單用法
來自:http://www.cnblogs.com/knowledgesea/p/3897665.html 1.简单的linq语法 //1 var ss = from r in db.Am_recPr ...