又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高。时间复杂度O(m)m为单词字母的个数;
数据结构:
class TrieNode {
char data;//字符
Map<Character,TrieNode> nodeMap;//子节点
int freqs;//频率
public TrieNode(char ch, int freqs){
this.data=ch;
this.freqs=freqs;
this.nodeMap=new HashMap<Character, TrieNode>();
}
}
字典树
public class TrieTree{
private static TrieNode root;//字典树的根节点默认为空;
public TrieTree() {
this.root = new TrieNode(' ',0);
}
public int query(String str){//查找字符串在字典树中出现的次数
TrieNode cur=root;//让cur指向根节点
for(int i=0;i<str.length();i++){//根据字符查找字典树
if(cur.nodeMap.get(str.charAt(i))!=null){
cur=cur.nodeMap.get(str.charAt(i));//如果找到就更新cur
}else{
return 0;
}
}
return cur.freqs;
}
public void delete(String str){
//删除的是要从尾到头删除
if (searchNode(str)==null) {
return;
}
TrieNode cur = root;
for (char c : str.toCharArray()) {
TrieNode child = cur.nodeMap.get(c);
if (child.freqs == 1) {
cur.nodeMap.remove(c);
return;
}else{
child.freqs--;
cur = child;
}
}
}
public TrieNode searchNode(String str){//寻找单词最后一个字母所在的节点
TrieNode cur=root;
for(int i=0;i<str.length();i++){
if(cur.nodeMap.get(str.charAt(i))!=null){
cur=cur.nodeMap.get(str.charAt(i));//如果找到就更新cur
}else {
return null;
}
}
return cur;
}
public void add(String str){//增加单词
TrieNode cur=root;
for(int i=0;i<str.length();i++){
if(cur.nodeMap.get(str.charAt(i))!=null){
cur.nodeMap.get(str.charAt(i)).freqs++;
cur=cur.nodeMap.get(str.charAt(i));//如果找到就更新cur
}else {
cur.nodeMap.put(str.charAt(i),new TrieNode(str.charAt(i),1));
cur=cur.nodeMap.get(str.charAt(i));
}
}
}
public String maxPreStr(){//求字典树上所有单词的最大前缀
String str="";
TrieNode cur=root;
while(cur.nodeMap.size()==1){//map表里的节点只有一个的时候
str+=cur.nodeMap.keySet().toString();
Iterator it=cur.nodeMap.keySet().iterator();
cur=cur.nodeMap.get((char)it.next());
}
return str;
}
}