Trie 树 及Java实现
来源:互联网 发布:淘宝商业计划书模板 编辑:程序博客网 时间:2024/06/05 21:17
来源于英文“retrieval”. Trie树就是字符树,其核心思想就是空间换时间。
举个简单的例子。
这题当然可以用hash来,但是我要介绍的是trie树。在某些方面它的用途更大。比如说对于某一个单词,我要询问它的前缀是否出现过。这样hash就不好搞了,而用trie还是很简单。
假设有b,abc,abd,bcd,abcd,efg,hii这6个单词,我们构建的树就是这样的。
对于每一个节点,从根遍历到他的过程就是一个单词,如果这个节点被标记为红色,就表示这个单词存在,否则不存在。
Trie树的java代码 实现如下:
import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class Trie{ private Vertex root;//一个Trie树有一个根节点 //内部类 protected class Vertex{//节点类 protected int words; protected int prefixes; protected Vertex[] edges;//每个节点包含26个子节点(类型为自身) Vertex() { words = 0; prefixes = 0; edges = new Vertex[26]; for (int i = 0; i < edges.length; i++) { edges[i] = null; } } } public Trie () { root = new Vertex(); } public List< String> listAllWords() { List< String> words = new ArrayList< String>(); Vertex[] edges = root.edges; for (int i = 0; i < edges.length; i++) { if (edges[i] != null) { String word = "" + (char)('a' + i); depthFirstSearchWords(words, edges[i], word); } } return words; } private void depthFirstSearchWords(List words, Vertex vertex, String wordSegment) { Vertex[] edges = vertex.edges; boolean hasChildren = false; for (int i = 0; i < edges.length; i++) { if (edges[i] != null) { hasChildren = true; String newWord = wordSegment + (char)('a' + i); depthFirstSearchWords(words, edges[i], newWord); } } if (!hasChildren) { words.add(wordSegment); } } public int countPrefixes(String prefix) { return countPrefixes(root, prefix); } private int countPrefixes(Vertex vertex, String prefixSegment) { if (prefixSegment.length() == 0) { //reach the last character of the word return vertex.prefixes; } char c = prefixSegment.charAt(0); int index = c - 'a'; if (vertex.edges[index] == null) { // the word does NOT exist return 0; } else { return countPrefixes(vertex.edges[index], prefixSegment.substring(1)); } } public int countWords(String word) { return countWords(root, word); } private int countWords(Vertex vertex, String wordSegment) { if (wordSegment.length() == 0) { //reach the last character of the word return vertex.words; } char c = wordSegment.charAt(0); int index = c - 'a'; if (vertex.edges[index] == null) { // the word does NOT exist return 0; } else { return countWords(vertex.edges[index], wordSegment.substring(1)); } } public void addWord(String word) { addWord(root, word); } private void addWord(Vertex vertex, String word) { if (word.length() == 0) { //if all characters of the word has been added vertex.words ++; } else { vertex.prefixes ++; char c = word.charAt(0); c = Character.toLowerCase(c); int index = c - 'a'; if (vertex.edges[index] == null) { //if the edge does NOT exist vertex.edges[index] = new Vertex(); } addWord(vertex.edges[index], word.substring(1)); //go the the next character } } public static void main(String args[]) //Just used for test { Trie trie = new Trie(); trie.addWord("China"); trie.addWord("China"); trie.addWord("China"); trie.addWord("crawl"); trie.addWord("crime"); trie.addWord("ban"); trie.addWord("China"); trie.addWord("english"); trie.addWord("establish"); trie.addWord("eat"); System.out.println(trie.root.prefixes); System.out.println(trie.root.words); List< String> list = trie.listAllWords(); Iterator listiterator = list.listIterator(); while(listiterator.hasNext()) { String s = (String)listiterator.next(); System.out.println(s); } int count = trie.countPrefixes("ch"); int count1=trie.countWords("china"); System.out.println("the count of c prefixes:"+count); System.out.println("the count of china countWords:"+count1); } }运行:C:\test>java Trie100banchinacrawlcrimeeatenglishestablishthe count of c prefixes:4the count of china countWords:4
0 0
- Trie 树 及Java实现
- Trie 树 及Java实现
- Trie 树 及Java实现
- Trie树,Java实现
- trie树Java实现
- Java实现Trie树
- Trie树-Java实现
- trie-字典树及实现
- 前缀树(Trie)原理及Java实现
- Trie树的java实现
- Trie树的Java实现
- HihoCoder Trie树 java实现
- 字典树-大量字符串前缀及出现次数是否存在统计(Trie树-java)算法实现
- 标准trie树(前缀树)的介绍及java实现
- 字典树-大量字符串前缀及出现次数是否存在统计(Trie树-java)算法实现
- trie树(字典树)java实现
- 256路Trie树的Java实现
- java实现的Trie树数据结构
- HDU 1536 S-Nim(组合游戏Nim)
- 在WPS中粘帖代码保持代码高亮
- 垃圾回收的一些面试题
- 计算机的存储介质介绍
- 标准trie树(前缀树)的介绍及java实现
- Trie 树 及Java实现
- Unity中使用SLua的一些注意事项
- Servlet生命周期
- UVA 147 Dollars
- 问题:oracle数据库可以拆开两方面来理解:怎样存储的空间安排 和 怎样控制操作?
- [Android]百度地图初使用(2)
- LintCode-剑指Offer-(105)复制带随机指针的链表
- 这算是断点续传的雏形么?
- 今天记起来的一些基础