一、概述

1.1 基本概念

字典树,又称为单词查找树,Tire数,是一种树形结构,它是一种哈希树的变种。

1.2 基本性质

  • 根节点不包含字符,除根节点外的每一个子节点都包含一个字符
  • 从根节点到某一节点。路径上经过的字符连接起来,就是该节点对应的字符串
  • 每个节点的所有子节点包含的字符都不相同

1.3 应用场景

典型应用是用于统计,排序和保存大量的字符串(不仅限于字符串),经常被搜索引擎系统用于文本词频统计。

1.4 优点

利用字符串的公共前缀来减少查询时间,最大限度的减少无谓的字符串比较,查询效率比哈希树高。

二、trie树的构建与操作实现

2.1 字典树节点定义

//定义字典表节点(简化设计,仅兼容26个小写英文字符)
class TrieNode {private int num; //有多少单词经过当前节点,即由根节点到该节点组成的字符串模式出现的次数private TrieNode[] son;//子节点数组private boolean wordEnd;//是否是叶子结点private char val;//当前节点的值TrieNode() {num =1;son = new TrieNode[engNum];wordEnd = false;}
}

2.2 字典树构造函数

public Trie() {root = new TrieNode();}

2.3 建立字典树

//建立字典树
public void insert(String str) {if(StringUtils.isEmpty(str)) {return;}TrieNode curNode = root;char[] arr = str.toCharArray();for(char c:arr) {int index = c-'a';TrieNode node = curNode.son[index];if(node == null) {//当前节点为空则创建curNode.son[index] = new TrieNode();curNode.son[index].val = c;}else {//不为空则加一node.num = node.num +1;}curNode = curNode.son[index];}curNode.wordEnd = true;
}

2.4 在字典树中查找是否完全匹配一个指定的字符串

//在字典中查找一个完全匹配的单词
public boolean has(String str) {if(StringUtils.isEmpty(str)) {return false;}TrieNode node = root;//找到指定前缀在字典树的位置char[] arr = str.toCharArray();for(int i=0;i<arr.length;i++) {int index = arr[i] -'a';if(node.son[index] == null) {return false;}node = node.son[index];}//到这里,如果最后的字符是叶子结点,则完全匹配;否则为部分匹配;return node.wordEnd;
}

2.5 前序遍历字典树

//前序遍历字典树
public void preTraverse(TrieNode root) {if(root != null) {System.out.println(root.val);for(TrieNode son: root.son) {preTraverse(son);}}
}

2.6 计算指定前缀的单词的数量

//计算指定前缀的单词的数量
public int countPrefix(String prefix) {if(StringUtils.isEmpty(prefix)) {return 0;}TrieNode node = root;char[] arr = prefix.toCharArray();for(int i=0;i<arr.length;i++) {int index = arr[i] -'a';if(node.son[index] == null) {return 0;}node = node.son[index];}return node.num;
}

2.7 完整代码


public class Trie {public static int asciiNum = 128;public static int engNum = 26;private TrieNode root;public Trie() {root = new TrieNode();}//定义字典表节点(简化设计,仅兼容26个小写英文字符)class TrieNode {private int num; //有多少单词经过当前节点,即由根节点到该节点组成的字符串模式出现的次数private TrieNode[] son;//子节点数组private boolean wordEnd;//是否是叶子结点private char val;//当前节点的值TrieNode() {num =1;son = new TrieNode[engNum];wordEnd = false;}}//建立字典树public void insert(String str) {if(StringUtils.isEmpty(str)) {return;}TrieNode curNode = root;char[] arr = str.toCharArray();for(char c:arr) {int index = c-'a';TrieNode node = curNode.son[index];if(node == null) {//当前节点为空则创建curNode.son[index] = new TrieNode();curNode.son[index].val = c;}else {//不为空则加一node.num = node.num +1;}curNode = curNode.son[index];}curNode.wordEnd = true;}//计算指定前缀的单词的数量public int countPrefix(String prefix) {if(StringUtils.isEmpty(prefix)) {return 0;}TrieNode node = root;char[] arr = prefix.toCharArray();for(int i=0;i<arr.length;i++) {int index = arr[i] -'a';if(node.son[index] == null) {return 0;}node = node.son[index];}return node.num;}//打印指定前缀的单词public void hasPrefix(String prefix) {if(StringUtils.isEmpty(prefix)) {return;}TrieNode node = root;//找到指定前缀在字典树的位置char[] arr = prefix.toCharArray();for(int i=0;i<arr.length;i++) {int index = arr[i] -'a';if(node.son[index] == null) {return;}node = node.son[index];}//前序遍历字典树preTraverse(node, prefix);}private void preTraverse(TrieNode node, String prefix) {if(node.wordEnd) {System.out.println(prefix);}for(TrieNode son : node.son) {if(son != null) {preTraverse(son, prefix + son.val);}}}//在字典中查找一个完全匹配的单词public boolean has(String str) {if(StringUtils.isEmpty(str)) {return false;}TrieNode node = root;//找到指定前缀在字典树的位置char[] arr = str.toCharArray();for(int i=0;i<arr.length;i++) {int index = arr[i] -'a';if(node.son[index] == null) {return false;}node = node.son[index];}//到这里,如果最后的字符是叶子结点,则完全匹配;否则为部分匹配;return node.wordEnd;}//前序遍历字典树public void preTraverse(TrieNode root) {if(root != null) {System.out.println(root.val);for(TrieNode son: root.son) {preTraverse(son);}}}public static void main(String[] args) {Trie trie = new Trie();String [] arr = new String[]{"string","str","study","strong","tech", "teach","teacher"};trie.insert("");for(String str: arr) { trie.insert(str);}
//      trie.preTraverse(trie.root);String prefix ="tea";System.out.println(trie.countPrefix(prefix));trie.hasPrefix(prefix);String word = "teach";System.out.println(trie.has(word));}}

字典树(Trie树)的原理与实现相关推荐

  1. HDU 1247 Hat’s Words 字典树(Trie树)

    HDU 1247 Hat's Words 字典树(Trie树) 字典树的建立是应该都是一样的 下面是我的做法: 建立完后, 对每一个单词都进行find_string()判断是否符合, 分别对其分成两半 ...

  2. java工具:字典树(单词查找树/Trie树)的实现以及使用

    项目地址 https://github.com/kylin-hunter/k-dic 文章目录 项目地址 前言 一.字典树 二.使用步骤 1 引入库 1.1 编译并发布到本地 1.2 gradle ( ...

  3. 字典树(trie树)、后缀树

    (1)字典树(Trie树) Trie是个简单但实用的数据结构,通常用于实现字典查询.我们做即时响应用户输入的AJAX搜索框时,就是Trie开始.本质上,Trie是一颗存储多个字符串的树.相邻节点间的边 ...

  4. 字典树(Trie树)

    Trie树就是字典树,其核心思想就是空间换时间. 举个简单的例子. 给你100000个长度不超过10的单词.对于每一个单词,我们要判断他出没出现过,如果出现了,第一次出现第几个位置. 这题当然可以用h ...

  5. 【BZOJ3217】ALOEXT-暴力重构线段树-替罪羊树-Trie树-树套树-10k大代码(+数据生成器)...

    Problem ALOEXT 题目大意 给出一个数据结构维护一个数列,要求支持以下操作: 向数列中某个位置插入一个数 将数列中某个位置的数删除 将数列中某个位置的数换成另外一个数 查询一段区间内的次大 ...

  6. LeetCode 14. Longest Common Prefix字典树 trie树 学习之 公共前缀字符串

    所有字符串的公共前缀最长字符串 特点:(1)公共所有字符串前缀 (好像跟没说一样...) (2)在字典树中特点:任意从根节点触发遇见第一个分支为止的字符集合即为目标串 参考问题:https://lee ...

  7. 【转】从Trie树(字典树)谈到后缀树

    本文第一部分,咱们就来了解这个Trie树,然后自然而然过渡到第二部分.后缀树,接着进入第三部分.详细阐述后缀树的构造方法-Ukkonen. 第一部分.Trie树 1.1.什么是Trie树 Trie树, ...

  8. Trie树 -- 高效的字典树

    文章目录 简介 原理 构造一棵Trie树 使用Trie树进行查询 实现 模拟(瞎暴力)实现 空间优化 简介 Trie树是一种数据结构,它有一个好听的中文名字,叫"字典树".顾名思义 ...

  9. 从Trie树(字典树)和后缀树

    从Trie树(字典树)谈到后缀树 转载:http://blog.csdn.net/v_july_v/article/details/6897097#t22 感谢作者,侵删. 引言 常关注本blog的读 ...

  10. Trie树(字典树)详细知识点及其应用

    Trie,又经常叫前缀树,字典树等等.它有很多变种,如后缀树,Radix Tree/Trie,PATRICIA tree,以及bitwise版本的crit-bit tree.当然很多名字的意义其实有交 ...

最新文章

  1. 再见了,Windows AutoRun!
  2. UML类图关系大全 and 报表的基本用法
  3. Sublime Text 3 初试牛刀
  4. 公开说说别人看不到_当听到别人在说自己坏话时,心里是什么感受?
  5. 使用Mfuzz包进行基因表达的时间趋势分析并划分聚类群
  6. 服务器挂存储系统启不,应用服务器重新启动后无法加载多路径软件
  7. 去除List集合中的重复元素,并保持原有数据的初始顺序
  8. MySQL获取月份最后一天
  9. js基础知识(pomelo阅读)
  10. C#3.0学习(2)---对象集合初始化器
  11. 基于Jersey框架创建web项目
  12. VBA-save as xlsm
  13. @【基础测绘计算】(坐标正反算)
  14. i9 9900es版,QQC0满载功耗测试
  15. 如何使用 FFmpeg 进行视频转码:字幕
  16. 交互组件滚动条,搜索框,上传组件,翻页的微创新
  17. Dataframe中na.fill的用法
  18. 酷狗音乐微信小程序插件使用实践
  19. R:字符串截取和匹配
  20. 【51nod】2059 上台阶 easy

热门文章

  1. qtabwidget切换tab事件_某超超临界机组初压/限压切换过程中扰动原因分析
  2. 查询工资最低的3名员工的职工工号、姓名和收入_普法课堂|你有多久没有收到工资条了?...
  3. python组件介绍_python 中的爬虫· scrapy框架 重要的组件的介绍
  4. html文本框整数范围,验证HTML表单文本框中的数值范围。 PHP或Javascript
  5. Unit Three-Program test
  6. 为什么接吻需要闭眼睛?
  7. 这种动作片还需要汽车特效?
  8. 程序员苦逼了6年,选择在街边做鸭......
  9. 世界上最诡异的画,到底为何让无数人闻风丧胆?
  10. 限时秒杀│中科院推荐!6个引自美国NASA盒子,玩转科学