Trie树详解
2016-07-23 12:41
197 查看
1、 概述
Trie树,又称字典树,单词查找树或者前缀树,是一种用于快速检索的多叉树结构,如英文字母的字典树是一个26叉树,数字的字典树是一个10叉树。Trie一词来自retrieve,发音为/tri:/ “tree”,也有人读为/traɪ/ “try”。Trie树可以利用字符串的公共前缀来节约存储空间。如下图所示,该trie树用10个节点保存了6个字符串tea,ten,to,in,inn,int:package IO; public class Trie { private int SIZE = 26; private TrieNode root;// 字典树的根 Trie(){ // 初始化字典树 root = new TrieNode(); } private class TrieNode{ //字典树节点 private int num;// 有多少单词通过这个节点,即由根至该节点组成的字符串模式出现的次数 private TrieNode[] son;// 所有的儿子节点 private boolean isEnd;// 是不是最后一个节点 private char val;// 节点的值 TrieNode() { num = 1; son = new TrieNode[SIZE]; isEnd = false; } } // 建立字典树 public void insert(String str){// 在字典树中插入一个单词 if (str == null || str.length() == 0) { return; } TrieNode node = root; char[] letters = str.toCharArray(); for (int i = 0, len = str.length(); i < len; i++) { int pos = letters[i] - 'a'; if (node.son[pos] == null) { node.son[pos] = new TrieNode(); node.son[pos].val = letters[i]; } else { node.son[pos].num++; } node = node.son[pos]; } node.isEnd = true; } // 计算单词前缀的数量 public int countPrefix(String prefix) { if (prefix == null || prefix.length() == 0) { return -1; } TrieNode node = root; char[] letters = prefix.toCharArray(); for (int i = 0, len = prefix.length(); i < len; i++) { int pos = letters[i] - 'a'; if (node.son[pos] == null) { return 0; } else { node = node.son[pos]; } } return node.num; } // 打印指定前缀的单词 public String hasPrefix(String prefix) { if (prefix == null || prefix.length() == 0) { return null; } TrieNode node = root; char[] letters = prefix.toCharArray(); for (int i = 0, len = prefix.length(); i < len; i++) { int pos = letters[i] - 'a'; if (node.son[pos] == null) { return null; } else { node = node.son[pos]; } } preTraverse(node, prefix); return null; } // 遍历经过此节点的单词. public void preTraverse(TrieNode node, String prefix) { if (!node.isEnd) { for (TrieNode child : node.son) { if (child != null) { preTraverse(child, prefix + child.val); } } return; } System.out.println(prefix); } // 在字典树中查找一个完全匹配的单词. public boolean has(String str) { if (str == null || str.length() == 0) { return false; } TrieNode node = root; char[] letters = str.toCharArray(); for (int i = 0, len = str.length(); i < len; i++) { int pos = letters[i] - 'a'; if (node.son[pos] != null) { node = node.son[pos]; } else { return false; } } return node.isEnd; } //前序遍历字典树. public void preTraverse(TrieNode node) { if (node != null) { System.out.print(node.val + "-"); for (TrieNode child : node.son) { preTraverse(child); } } } public TrieNode getRoot() { return this.root; } public static void main(String[] args) { Trie tree = new Trie(); String[] strs = { "banana", "band", "bee", "absolute", "acm", }; String[] prefix = { "ba", "b", "band", "abc", }; for (String str : strs) { tree.insert(str); } System.out.println(tree.has("abc")); tree.preTraverse(tree.getRoot()); System.out.println(); for (String pre : prefix) { int num = tree.countPrefix(pre); System.out.println(pre + "" + num); } } }
View Code
相关文章推荐
- 373. Find K Pairs with Smallest Sums && 378. Kth Smallest Element in a Sorted Matrix
- linux ls正则表达式
- 【Mariadb】centos7搭建mariadb Galera集群
- Android提高启动速度的实现方法 7.23
- soft raid5阅读笔记之七--MD中的bitmap
- map.c 添加注释
- H5学习之4 拖拽元素 放置元素2
- 状态模式(State)
- ios创建空项目
- vector::begin
- Openstack贡献者须知 2 — 社区工作运作 & 代码贡献流程
- 解决磁盘io紧张的一种临时方法
- 通道类型
- Git 一篇搞定基本操作
- 文件系统缓存dirty_ratio与dirty_background_ratio两个参数区别
- Redis教程分享系列:1.Redis基础入门
- ggplot2--legend图例的修改
- session与cookie的区别---
- Java泛型的实现:原理与问题
- 复杂度nlog(n)之归并排序