字典树Java实现
Trie树的原理
Trie树也称字典树,因为其效率很高,所以在在字符串查找、前缀匹配等中应用很广泛,其高效率是以空间为代价的。
利用串构建一个字典树,这个字典树保存了串的公共前缀信息,因此可以降低查询操作的复杂度。下面以英文单词构建的字典树为例,这棵Trie树中每个结点包括26个孩子结点,因为总共有26个英文字母(假设单词都是小写字母组成)。
详细介绍请参考:http://www.cnblogs.com/dolphin0520/archive/2011/10/11/2207886.html 等
字典树模版(Java)
1 /** 2 * 字典树模版,默认只包含26个小写字母 3 * 提供hasStr、insert、countPrefix、preWalk、getRoot接口 4 * @author 5 */ 6 public class TrieTree { 7 8 private final int SIZE = 26; //每个节点能包含的子节点数,即需要SIZE个指针来指向其孩子 9 private Node root; //字典树的根节点 10 11 /** 12 * 字典树节点类 13 * @author Lenovo 14 */ 15 private class Node { 16 private boolean isStr; //标识该节点是否为某一字符串终端节点 17 private int num; //标识经过该节点的字符串数。在计算前缀包含的时候会用到 18 private Node[] child; //该节点的子节点 19 20 public Node() { 21 child = new Node[SIZE]; 22 isStr = false; 23 num = 1; 24 } 25 } 26 27 public TrieTree() { 28 root = new Node(); 29 } 30 31 /** 32 * 检查字典树中是否完全包含字符串word 33 * @param word 34 * @return 35 */ 36 public boolean hasStr(String word) { 37 Node pNode = this.root; 38 39 //逐个字符去检查 40 for (int i = 0; i < word.length(); i++) { 41 int index = word.charAt(i) - 'a'; 42 //在字典树中没有对应的节点,或者word字符串的最后一个字符在字典树中检测对应节点的isStr属性为false,则返回false 43 if (pNode.child[index] == null 44 || (i + 1 == word.length() && pNode.child[index].isStr == false)) { 45 return false; 46 } 47 pNode = pNode.child[index]; 48 } 49 50 return true; 51 } 52 53 /** 54 * 在字典树中插入一个单词 55 * @param word 56 */ 57 public void insert(String word) { 58 if (word == null || word.isEmpty()) { 59 return; 60 } 61 Node pNode = this.root; 62 for (int i = 0; i < word.length(); i++) { 63 int index = word.charAt(i) - 'a'; 64 if (pNode.child[index] == null) { //如果不存在节点,则new一个一节点插入字典树 65 Node tmpNode = new Node(); 66 pNode.child[index] = tmpNode; 67 } else { 68 pNode.child[index].num++; //如果字典树中改路径上存在节点,则num加1,表示在该节点上有一个新的单词经过 69 } 70 pNode = pNode.child[index]; 71 } 72 pNode.isStr = true; 73 } 74 75 /** 76 * 统计在字典树中有多少个单词是以str为前缀的 77 * @param str 78 * @return 79 */ 80 public int countPrefix(String str) { 81 Node pNode = this.root; 82 for (int i = 0; i < str.length(); i++) { 83 int index = str.charAt(i) - 'a'; 84 if (pNode.child[index] == null) { 85 return 0; 86 } else { 87 pNode = pNode.child[index]; 88 } 89 } 90 91 return pNode.num; 92 } 93 94 /** 95 * 先序遍历 96 * @param root 97 */ 98 public void preWalk(Node root) { 99 Node pNode = root; 100 for (int i = 0; i < SIZE; i++) { 101 if (pNode.child[i] != null) { 102 System.out.print((char) ('a' + i) + "--"); 103 preWalk(pNode.child[i]); 104 } 105 } 106 } 107 108 /** 109 * 返回字典树根节点 110 * @return 111 */ 112 public Node getRoot() { 113 return root; 114 } 115 116 }