初识字典树(Trie Tree)

Trie树属于树形结构,查询效率比红黑树和哈希表都要快。假设有这么一种应用场景:有若干个英文单词,需要快速查找某个单词是否存在于字典中。使用Trie时先从根节点开始查找,直至匹配到给出字符串的最后一个节点。在建立字典树结构时,预先把带有相同前缀的单词合并在同一节点,直至两个单词的某一个字母不同,则再从发生差异的节点中分叉一个子节点。

节点结构:

每个节点对应一个最大可储存字符数组。假设字典只存26个小写英文字母,那么每个节点下应该有一个长度为26的数组。换言说,可存的元素类型越多,单个节点占用内存越大。如果用字典树储存汉字,那么每个节点必须为数千个常用汉字开辟一个数组作为储存空间,占用的内存实在不是一个数量级。不过Trie树就是一种用空间换时间的数据结构,鱼和熊掌往往不可兼得。

建树细节:

  • 取要插入字符串的首个字符,从根节点的孩子节点开始,匹配当前字符是否已有节点,有则把指针指向该节点。无则为该字符创建节点,并把指针指向该新建节点。
  • 迭代。
  • 遇到要插入字符串末尾结束符时停止迭代,并把最后一个非’\0’字符对应的节点设为末端节点。

查找细节:

循环取要插入字符串的首个字符,从根节点的孩子节点开始,匹配当前字符是否已有节点,有则继续循环,无则返回False. 直至匹配到最后一个字符则完成查找。

实例:

我们用apps, apply, apple, append, back, basic, backen几英文单词创建树形结构:

《初识字典树(Trie Tree)》

Sample Input 
banana 
band 
bee 
absolute 
acm 

ba 

band 
abc 

Sample Output 



public class Trie {     
    private int SIZE = 26;
    private TrieNode root;  //字典树的根
  
    Trie() {  //初始化字典树
        root = new TrieNode();  
    }  
  
    private class TrieNode {  //字典树节点
        private int num;//有多少单词通过这个节点,即节点字符出现的次数 
        private TrieNode[] son;// 所有的儿子节点
        private boolean isEnd;//是不是最后一个节点
        private char val;// 节点的值 
        
  
        TrieNode() {  
            num = 1; 
            son = new TrieNode[SIZE];  
            isEnd = false;  
           
        }  
    }  
  //建立字典树
    public void insert(String str) {  //在字典树中插入一个单词
        if (str == null || str.length() == 0) {  
            return;
        }  
        TrieNode node = root;  
        char[] letters=str.toCharArray();  
        for (int i = 0, len = str.length(); i < len; i++) {  
            int pos = letters[i] - 'a';  
            if (node.son[pos] == null) {  
                node.son[pos] = new TrieNode();  
                node.son[pos].val = letters[i];  
            } else {  
                node.son[pos].num++; 
            }  
            node = node.son[pos];  
        }  
        node.isEnd = true;  
    }  
  
     
    public int countPrefix(String prefix){  //计算单词前缀的数量
        if(prefix==null||prefix.length()==0){  
            return -1;  
        }  
        TrieNode node=root;  
        char[] letters=prefix.toCharArray();  
        for(int i=0,len=prefix.length();i< len;i++){  
            int pos=letters[i]-'a';  
            if(node.son[pos]==null){  
                return 0;  
            }else{  
                node=node.son[pos];  
            }  
        }  
        return node.num;  
    }  
      
    // 在字典树中查找一个完全匹配的单词.  
    public boolean has(String str) {  
        if (str == null || str.length() == 0) {  
            return false;  
        }  
        TrieNode node = root;  
        char[] letters=str.toCharArray();  
        for (int i = 0, len = str.length(); i < len; i++) {  
            int pos = letters[i] - 'a';  
            if (node.son[pos] != null) {  
                node = node.son[pos];  
            } else {  
                return false;  
            }  
        }  
        return node.isEnd;  
    }  
  
    
    //前序遍历字典树.  
    public void preTraverse(TrieNode node){  
        if(node!=null){  
            System.out.print(node.val+"-");  
            for(TrieNode child: node.son){  
                preTraverse(child);  
            }  
        }  
          
    }  
   
    public TrieNode getRoot(){  
        return this.root;  
    }  
      
    public static void main(String[] args) {  
        Trie tree = new Trie();  
        String[] strs={  
                "banana",
                "band",
                "bee",
                "absolute",
                "acm",
        };
        String[] prefix={
                "ba",
                "b",
                "band",
                "abc",
        };
        for(String str : strs){  
            tree.insert(str);
        }  
        System.out.println(tree.has("abc"));  
        tree.preTraverse(tree.getRoot());  
        System.out.println();  
        //tree.printAllWords();  
        for(String pre : prefix){  
            int num=tree.countPrefix(pre);  
            System.out.println(pre+" "+num);  
        }  
          
    }  
}  

参考:http://powman.org/archives/trie.html   http://www.java3z.com/cwbwebhome/article/article8/83591.html?id=4750

    原文作者:Trie树
    原文地址: https://blog.csdn.net/Emily_cyy/article/details/39645723
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞