字典树(TrieTree),一般又称为单词查找树,是一种树形结构,常用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。
如当输入一个网址,可以自动搜索出可能的选择。当没有完全匹配的搜索结果,可以返回前缀最相似的可能。
优点: 最大限度的减少无谓的比较,查询效率比哈希高。
核心思想: 利用字符串的公共前缀来降低查询时间,达到提高查询的目的。
缺点: 空间消耗比较大。
基本性质:
根节点不包含字符,除根节点外每个节点都只包含一个字符;
从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串;
每个节点的所有子节点包含的字符都不相同。
代码实现
1 定义节点类和trie结构
class TrieTree{
// 定义常量,表示字符的个数
private static final int LETTER_SIZE = 26;
// 字典树的根节点
private Entry root;
/**
* 字典树的初始化,根节点不包含字符
*/
public TrieTree(){
root = new Entry(null, 0);
}
/**
* 给字典树增加一个单词 "hello"
* @param word
*/
public void add(String word){
// 1.root word eat
Entry cur = root;
for(int i=0; i<word.length(); ++i){
char ch = word.charAt(i);
if(cur.next[ch-'a'] == null){
cur.next[ch-'a'] = new Entry(ch, 0);
} else{
cur.next[ch-'a'].freq++;
}
cur = cur.next[ch-'a'];
}
// cur指向了最后一个节点
cur.count++;
}
/**
* 求出word单词出现的次数
* @param word
* @return
*/
public int count(String word){
Entry cur = root;
for(int i=0; i<word.length(); ++i){
char ch = word.charAt(i);
if(cur.next[ch-'a'] == null){
return 0;
}
cur = cur.next[ch-'a'];
}
// cur -> 最后一个节点 next "hel" "hello" "helllo"
return cur.count;
}
2 字典树中节点的类型
static class Entry{
Character ch; // 表示字典树上存储节点中的字符
int freq; // 记录每一个字符使用的次数
int count; // 表示以某一个字符结尾的单词的个数
Entry[] next; // 当前字符后面的所有出现的字符
public Entry(Character ch, int freq) {
this.ch = ch;
this.freq = freq;
this.count = 0;
this.next = new Entry[LETTER_SIZE];
}
public Character getCh() {
return ch;
}
public void setCh(Character ch) {
this.ch = ch;
}
public int getFreq() {
return freq;
}
public void setFreq(int freq) {
this.freq = freq;
}
public Entry[] getNext() {
return next;
}
public void setNext(Entry[] next) {
this.next = next;
}
}
}
3 写测试代码,查看效果
public static void main(String[] args) {
TrieTree tt = new TrieTree();
tt.add("prize");
tt.add("pool");
tt.add("prize");
tt.add("prize");
tt.add("prizewerq");
tt.add("prizewytry");
tt.add("abbcde");
tt.add("abcdr");
System.out.println(tt.count("prize"));
4 运行程序,结果符合预期