数据结构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图及其应用.当然这些都是比较高级的数据结构和算法,而这里面最常用和最熟 ...
随机推荐
- 购物车redis存储结构
- 自创open vp n windows步骤
Easy Windows Guide¶ This page contains a no-frills guide to getting OpenVPN up and running on a Wind ...
- 从golang-gin-realworld-example-app项目学写httpapi (三)
https://github.com/gothinkster/golang-gin-realworld-example-app/blob/master/users/serializers.go 序列化 ...
- leetcode Ch7-Graph Search
1. Clone Graph BFS: class Solution { public: typedef UndirectedGraphNode UGNode; UndirectedGraphNode ...
- css网页中设置背景图片的方法详解
在css代码中设置背景图片的方法,包括背景图片.背景重复.背景固定.背景定位等 用css设置网页中的背景图片,主要有如下几个属性: 1,背景颜色 {">说明:参数取值和颜色属性一样 ...
- VS :不会命中断点 代码版本与原始版本不同
设置了断点,但是无法中断,提示"不会命中断点 代码版本与原始版本不同".这种情况下一般是生成的bin\debug下面的文件与实际代码不符. 但是这次确实没有问题,重新更新程序,清理 ...
- How to rename table name
How to rename table name eg. rename emp to emp01; see aslo: https://docs.oracle.com/javadb/10.8.3.0 ...
- linux下常用命令:
常用指令 ls 显示文件或目录 -l 列出文件详细信息l(list) -a 列出当前目录下所有文件及目录,包括隐藏的a(all) mkdir ...
- TCP (传输控制协议)
http://baike.baidu.com/item/TCP/33012?fr=aladdin TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的.可 ...
- gluoncv faster_rcnn 参数修改
https://github.com/dmlc/gluon-cv/blob/master/gluoncv/model_zoo/faster_rcnn/faster_rcnn.py 对你选用的模块,修改 ...