又称单词查找树,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;

     }
 }