
字典树(java实现)
根节点特性:根节点不包含字符,其余每个节点仅包含一个字符。 节点路径特性:从根节点到某一节点的路径字符连接即为该节点对应的字符串。 子节点特性:每个节点的子节点字符互不相同。 插入操作:将单词逐一插入树中,检查每个字符是否存在: 示例:以单词 查找单词:从根节点开始,逐字符检查是否存在对应节点。 终止条件:若某字符路径不存在,则该单词不存在于树中。
发布日期:2021-05-08 19:32:04
浏览次数:26
分类:精选文章
本文共 4176 字,大约阅读时间需要 13 分钟。
字典树(Java 实现)
一、概念
Trie树(字典树)是一种树形数据结构,常用于解决字符串的统计、排序及查找问题。它通过空间换时间的原则,最大限度地减少无谓的字符串比较,显著提高查询效率。
Trie的核心思想在于利用字符串的公共前缀来降低查询时间开销。通过共享前缀,Trie能够高效地存储和检索大量字符串数据。
二、Trie 核心性质
三、Trie 树构建
Trie树的构建过程如下:
- 存在时,沿着路径继续。
- 不存在时,创建新节点,并更新父节点的统计信息。
add
为例,插入步骤如下: a
已存在,进入节点a
。d
已存在,进入节点ad
。d
不存在,创建新节点add
,标记为叶节点。
四、查询操作
五、复杂度分析
Trie树的时间复杂度为 O(长度),插入和查询效率显著高于哈希表。
六、Java 实现代码
import java.util.HashMap;public class TrieTree { private class Node { private int prefixNum; // 前缀数目 private int duplicateNum; // 重复数目 private Node[] children; // 子节点数组 private boolean isLeaf; // 是否为叶节点 Node() { prefixNum = 0; duplicateNum = 0; isLeaf = false; children = new Node[26]; } } private Node root; public TrieTree() { root = new Node(); } public void insert(String word) { insert(root, word.toLowerCase()); } private void insert(Node root, String word) { char[] chars = word.toCharArray(); for (int i = 0; i < chars.length; i++) { char c = chars[i]; int index = c - 'a'; if (root.children[index] != null) { root = root.children[index]; } else { Node newNode = new Node(); root.children[index] = newNode; root = newNode; if (i == chars.length - 1) { newNode.isLeaf = true; } } } } public HashMapgetAllWords() { return preTraversal(root, ""); } private HashMap preTraversal(Node root, String prefix) { HashMap map = new HashMap<>(); if (root != null) { if (root.isLeaf) { map.put(prefix, root.duplicateNum); } for (int i = 0; i < root.children.length; i++) { if (root.children[i] != null) { String nextPrefix = prefix + (char) ('a' + i); map.putAll(preTraversal(root.children[i], nextPrefix)); } } } return map; } public boolean isExist(String word) { return search(root, word.toLowerCase()); } private boolean search(Node root, String word) { if (root == null) { return false; } if (word.isEmpty()) { return true; // 根节点代表空字符串 } char c = word.charAt(0); int index = c - 'a'; if (root.children[index] == null) { return false; } return search(root.children[index], word.substring(1)); } public HashMap getWordsForPrefix(String prefix) { return getWordsForPrefix(root, prefix.toLowerCase()); } private HashMap getWordsForPrefix(Node root, String prefix) { HashMap map = new HashMap<>(); if (root == null) { return map; } char[] chars = prefix.toCharArray(); for (int i = 0; i < chars.length; i++) { char c = chars[i]; int index = c - 'a'; if (root.children[index] == null) { return map; } root = root.children[index]; } String currentPrefix = prefix; return preTraversal(root, currentPrefix); } public static void main(String[] args) { TrieTree trie = new TrieTree(); trie.insert("i"); trie.insert("love"); trie.insert("china"); trie.insert("xiaoliang"); trie.insert("man"); trie.insert("handsome"); trie.insert("love"); trie.insert("chinaha"); trie.insert("her"); trie.insert("know"); HashMap allWords = trie.getAllWords(); System.out.println("所有单词及出现次数:"); for (String word : allWords.keySet()) { System.out.println(word + " 出现: " + allWords.get(word) + "次"); } HashMap chinWords = trie.getWordsForPrefix("chin"); System.out.println("\n包含 chin(包括本身)前缀的单词及出现次数:"); for (String word : chinWords.keySet()) { System.out.println(word + " 出现: " + chinWords.get(word) + "次"); } System.out.println("\n字典树中不存在:" + (trie.isExist("xiaoming") ? "" : "不存在")); }}
七、总结
Trie树通过共享前缀优化存储和查询效率,适用于大规模字符串数据处理。Java实现代码展示了其核心逻辑和应用场景。
发表评论
最新留言
路过按个爪印,很不错,赞一个!
[***.219.124.196]2025年04月03日 13时51分58秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
Requests实践详解
2019-03-06
接口测试简介
2019-03-06
Golang Web入门(4):如何设计API
2019-03-06
让sublime实现js控制台(前提是安装了nodejs)
2019-03-06
树莓派连接二手液晶屏小记
2019-03-06
error: 'LOG_TAG' macro redefined
2019-03-06
android10Binder(一)servicemanager启动流程
2019-03-06
ES6基础之——new Set
2019-03-06
nodeJS实现识别验证码(tesseract-ocr+GraphicsMagick)
2019-03-06
玩玩小爬虫——试搭小架构
2019-03-06
AS与.net的交互——加载web上的xml
2019-03-06
Javascript之旅——第八站:说说instanceof踩了一个坑
2019-03-06
Javascript之旅——第九站:吐槽function
2019-03-06
Javascript之旅——第十一站:原型也不好理解?
2019-03-06
Sql Server之旅——第十站 看看DML操作对索引的影响
2019-03-06
十五天精通WCF——第二天 告别烦恼的config配置
2019-03-06
双十一来了,别让你的mongodb宕机了
2019-03-06
asp.net mvc 之旅 —— 第六站 ActionFilter的应用及源码分析
2019-03-06
Tomcat 热部署
2019-03-06
深入解析 HTTP 缓存控制
2019-03-06