数据结构之字典树

164 阅读2分钟

「这是我参与2022首次更文挑战的第20天,活动详情查看:2022首次更文挑战」。

字典树定义

又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高。

字典树的性质

它有3个基本性质:

根节点不包含字符,除根节点外每一个节点都只包含一个字符; 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串; 每个节点的所有子节点包含的字符都不相同。

字典树的构造

由字典树的性质我们可以很容易得到字典树的构造方法,这里我们将字符串倒序存入。

//    class tree{
//        tree[] child=new tree[26];
//        boolean end;
//        char value;
//        tree(char value){
//            this.value=value;
//        }
//        tree(){
//
//        }
//    }
tree root=new tree();
for (String s : dictionary) {
    tree occur=root;
    for(int i=s.length()-1; i>=0; i--){
        if(occur.child[s.charAt(i)-'a']==null)occur.child[s.charAt(i)-'a']=new tree(s.charAt(i));
        occur=occur.child[s.charAt(i)-'a'];
        if(i==0)occur.end=true;
    }
}

例题

题目描述

leetcode上的一道字典树题目

题解

数据结构:字典树

算法: 用字典树将smalls存进去,接着遍历big下标i,寻找以i开始的所有字符串,将结果保存。

class Solution {
    class Tree{
        char value;
        Tree[] child=new Tree[26];
        boolean isWord;
        Tree(char value){
            this.value=value;
        }
        Tree(){

        }
    }
    class dicTree{
        Tree root=new Tree();
        void buildTree(String word){
            Tree occur=root;
            for(int i=0; i<word.length(); i++){
                if(occur.child[word.charAt(i)-'a']==null)occur.child[word.charAt(i)-'a']=new Tree(word.charAt(i));
                occur=occur.child[word.charAt(i)-'a'];
                if(i==word.length()-1)occur.isWord=true;
            }
        }
        void updateAns(String key,int pos){
            Tree occur=root;
            int x=pos;
            StringBuilder stringBuilder=new StringBuilder();
            while(x<key.length()){
                if(occur.child[key.charAt(x)-'a']==null)return;
                occur=occur.child[key.charAt(x)-'a'];
                stringBuilder.append(occur.value);
                if(occur.isWord){
                    int index=strToPos.get(stringBuilder.toString());
                        ArrayList<Integer> tmp=arrayList.get(index);
                        tmp.add(pos);
                }
                x++;
            }
        }
    }
    HashMap<String,Integer> strToPos;
    ArrayList<ArrayList<Integer>> arrayList;
    public int[][] multiSearch(String big, String[] smalls) {
        arrayList=new ArrayList<>();
        for(int i=0; i<smalls.length; i++){
            arrayList.add(new ArrayList<>());
        }
        strToPos=new HashMap<>();
        dicTree dic=new dicTree();
        for (int i = 0; i < smalls.length; i++) {
            dic.buildTree(smalls[i]);
            strToPos.put(smalls[i],i);
        }
        for(int i=0; i<big.length(); i++){
            int pos=i;
            dic.updateAns(big,pos);
        }
        int[][] ans=new int[smalls.length][];
        for(int i=0; i<ans.length; i++){
            ans[i]=new int[arrayList.get(i).size()];
            for(int j=0; j<ans[i].length;j++){
                ans[i][j]=arrayList.get(i).get(j);
            }
        }
        return ans;
    }
}