字典树
又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高。(From baike)
它有三个基本性质:
(1)根节点不存储字符
(2)除根节点外每一个节点都只存储一个字符
(3)从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串,每个节点的所有子节点包含的字符都不相同。
Java实现代码(注释详细):
1 package com.wxisme.trietree; 2 3 /** 4 *Trie树的实现 5 *@author wxisme 6 *@time 2015-10-13 下午9:48:30 7 */ 8 public class TrieTree { 9 10 private final int SIZE = 26;//字符出现的种类数,以所有的小写字母为例 11 12 private int nodeNumber;//子节点的个数 13 14 private int depth;//树的深度 15 16 private TrieNode root;//树根 17 18 public TrieTree() { 19 this.nodeNumber = 0; 20 this.depth = 0; 21 this.root = new TrieNode(); 22 } 23 24 /** 25 * 节点结构 26 * @author wxisme 27 * 28 */ 29 private class TrieNode { 30 private char val;//节点值 31 32 private TrieNode son[];//子节点数组 33 34 private boolean isEnd;//是否有以此节点为结束字符的单词 35 36 private int pearNumber;//节点出现的次数 37 38 public TrieNode() { 39 this.isEnd = false; 40 this.pearNumber = 0; 41 this.son = new TrieNode[SIZE]; 42 } 43 } 44 45 /** 46 * 向Trie中插入一个word 47 * @param word 48 */ 49 public void insert(String word) { 50 char[] wordChars = word.toCharArray(); 51 52 TrieNode node = this.root; 53 54 for(char ch : wordChars) { 55 int pos = ch - ‘a‘; 56 //如果相应位置为空则创建 57 if(node.son[pos] == null) { 58 node.son[pos] = new TrieNode(); 59 node.son[pos].val = ch; 60 node.pearNumber = 1;//第一次出现 61 this.nodeNumber ++; 62 } 63 else {//已经有该字符 64 node.pearNumber ++; 65 } 66 node = node.son[pos]; 67 } 68 node.isEnd = true; 69 this.depth = Math.max(this.depth, word.length()); 70 } 71 72 /** 73 * 查找是否存在单词word 74 * @param word 75 * @return 结果 76 */ 77 public boolean search(String word) { 78 char[] wordChars = word.toCharArray(); 79 80 TrieNode node = this.root; 81 82 for(char ch : wordChars) { 83 int pos = ch - ‘a‘; 84 if(node.son[pos] != null) { 85 node = node.son[pos];//继续向下查找 86 } 87 else { 88 return false; 89 } 90 } 91 92 return node.isEnd; 93 } 94 95 /** 96 * 查找是否存在以word为前缀的单词,和search()类似,只是不用判断边界。 97 * @param word 98 * @return 结果 99 */ 100 public boolean searchPrefix(String word) { 101 char[] wordChars = word.toCharArray(); 102 103 TrieNode node = this.root; 104 105 for(char ch : wordChars) { 106 int pos = ch - ‘a‘; 107 if(node.son[pos] != null) { 108 node = node.son[pos];//继续向下查找 109 } 110 else { 111 return false; 112 } 113 } 114 115 return true; 116 } 117 118 /** 119 * 统计单词出现的次数 120 * @param word 121 * @return 结果 122 */ 123 public int wordCount(String word) { 124 char[] wordChars = word.toCharArray(); 125 126 TrieNode node = this.root; 127 128 for(char ch : wordChars) { 129 int pos = ch - ‘a‘; 130 if(node.son[pos] == null) { 131 return 0; 132 } 133 else { 134 node = node.son[pos]; 135 } 136 } 137 138 return node.isEnd?node.pearNumber:0; 139 } 140 141 142 /** 143 * 统计以word为前缀的单词个数 144 * @param word 145 * @return 结果 146 */ 147 public int wordPrefixCount(String word) { 148 char[] wordChars = word.toCharArray(); 149 150 TrieNode node = this.root; 151 152 for(char ch : wordChars) { 153 int pos = ch - ‘a‘; 154 if(node.son[pos] == null) { 155 return 0; 156 } 157 else { 158 node = node.son[pos]; 159 } 160 } 161 162 return node.pearNumber; 163 } 164 165 /** 166 * 深度优先遍历Trie树 167 * @param root 168 */ 169 public void traversal(TrieNode root) { 170 if(root == null) { 171 return; 172 } 173 for(TrieNode node : root.son) { 174 System.out.println(node.val); 175 traversal(node); 176 } 177 } 178 179 public int getNodeNumber() { 180 return nodeNumber; 181 } 182 183 public int getDepth() { 184 return depth; 185 } 186 187 public TrieNode getRoot() { 188 return root; 189 } 190 191 }
看一个Leetcode应用:http://www.cnblogs.com/wxisme/p/4875309.html
时间: 2024-10-16 17:36:31