数据结构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图及其应用.当然这些都是比较高级的数据结构和算法,而这里面最常用和最熟 ...
随机推荐
- INFA Transformation组件
RouterRouter和Filter很相似,Router可以用一或多个Filter来取代,不同的是用Router来生成多个组时输入数据只需处理一次,所以效率更高:Router 由一个输入组,一到多个 ...
- javascript中简单提示框
CSS部分 .help-tip{ width: 340px; border:1px solid #A0A0A0; background-color: #F8F8F8; border-radius: 5 ...
- 译文 [ROM][多国语言][2015.06.11] Lenovo S750 (MTK6589) - andrea_d86-lenovos750-4.2.2
************************************************** andrea_d86-lenovos750-4.2.2-150530 ************** ...
- 乘风破浪:LeetCode真题_009_Palindrome Number
乘风破浪:LeetCode真题_009_Palindrome Number 一.前言 如何判断一个整型数字是回文呢,我们可能会转换成String来做,但是还有更简单的方法. 二.Palindrome ...
- Kendo UI 的 k-template
官网上的例子: 1. <span id="output"></span><script>var template = kendo.templat ...
- php中的static
静态成员是一种类变量,可以把它看成时属于整个类而不是属于类的某个实例.与一般的实例变量不同的是,静态成员只保留一个变量值,而这个变量值对所有的实例都是有效的,也就是说,所有的实例共享这个成员. $th ...
- 第一次课堂作业之Circle
1.问题描述: Create a program that asks for the radius of a circle and prints the area of that circle, us ...
- 通用型正方教务(通杀各版本)存在注入(不需登陆)+获得webshell+提权内网漫游
某个接口页面存在oracle盲注,可以获得当前用户数据库,dump教师用户表,分析密文加密特征(前人研究成果+基友助攻),破译加密的密码.前台管理员登陆,后台文件上传基于黑名单原理,过滤u完全,上传特 ...
- C++派生类成员访问作用域,同名重载
#include <iostream> using namespace std; class CFatherSum //父类Sum { public: int m_iVar; //公用数据 ...
- 用Web技术开发客户端(一)
http://www.cnblogs.com/lefan/archive/2012/12/27/2836400.html 范怀宇(@duguguiyu)分享了<豌豆荚2.0重构时遇到的坑> ...