TRIE 介绍

Trie,又经常叫前缀树,字典树等,

基本性质

1,根节点不包含字符,除根节点意外每个节点只包含一个字符。

2,从根节点到某一个节点,路径上经过的字符连接起来,为该节点对应的字符串。 

3,每个节点的所有子节点包含的字符串不相同

 

优点:

可以最大限度地减少无谓的字符串比较,故可以用于词频统计和大量字符串排序。

  跟哈希表比较:

    1,最坏情况时间复杂度比hash表好

    2,没有冲突,除非一个key对应多个值(除key外的其他信息)

    3,自带排序功能(类似Radix Sort),中序遍历trie可以得到排序。

缺点:

内存消耗非常大

应用场景:

(1) 字符串检索

(2)文本预测、自动完成,see also,拼写检查

(3)词频统计

(4)排序

(5)字符串最长公共前缀

(6)字符串搜索的前缀匹配

(7) 作为其他数据结构和算法的辅助结构

 

 

递归实现样例:

定义树

class TrieNode{

        // 节点内容
        char word;
        // 子节点
        Map<Character,TrieNode> childMap;
        // 是否字符串结尾
        Boolean isEnd= true;

        public TrieNode(){
            this.isEnd=false;
            this.childMap = new HashMap<>();
        }
 }

 

新增

    public void recursionAdd(TrieNode root,String word) {
        add(root, word, 0);
    }

    /**
     * 递归写法调用方法实现递归添加
     *
     * @param node 传入要进行添加的节点
     * @param word 传入要进行添加的单词
     */
    public void add(TrieNode node, String word, int index) {
        if (!node.isEnd && index == word.length()) {
            node.isEnd = true;
        }

        if (word.length() > index) {
            char addLetter = word.charAt(index);
            if (node.childMap.get(addLetter) == null) {
                node.childMap.put(addLetter, new TrieNode());
            }
            // 基于已经存在的字符进行下个字符的递归查询
            add(node.childMap.get(addLetter), word, index + 1);
        }
    }

 

删除

    public  void deleteWord(TrieNode root , String word){
        if(!recursionContains(root, word)){
            return;
        }
        delete(root,word,0);
    }
    /**
     * 删除Trie中word递归写法(1,叶子节点删除;2,公用节点设置结尾标示为false)
     *
     * @param node
     * @param word
     * @param index
     * @return
     */
    public  Boolean delete(TrieNode node,String word,int i){

        Boolean isDel = false;

        // 字符串最后一个字节
        if(i == word.length()){
            if(CollectionUtils.isEmpty(node.childMap)){
                node = null;
                isDel = true;
            }else{
                node.isEnd = false;
                isDel  = false;
            }
        }
        else{
            char local = word.charAt(i);
            if(delete(node.childMap.get(local),word,i+1)){
                if(node.isEnd){
                    isDel = false;
                }else if(!CollectionUtils.isEmpty(node.childMap)){
                    isDel = false;

                }else{
                    node = null;
                    isDel = true;
                }
            }else{
                isDel = false;
            }
        }
        return isDel;

    }

 

查询

    public boolean recursionContains(TrieNode root,String word) {
        return contains(root, word, 0);
    }

    /**
     * 查询word中是否在Trie中递归写法
     *
     * @param node
     * @param word
     * @param index
     * @return
     */
    private boolean contains(TrieNode node, String word, int index) {
        if (index == word.length()) {
            return node.isEnd;
        }
        char c = word.charAt(index);
        if (node.childMap.get(c) == null) {
            return false;
        } else {
            return contains(node.childMap.get(c), word, index + 1);
        }
    }

 

上一篇:【python】Leetcode每日一题-前缀树(Trie)


下一篇:数据结构与算法:Aho‐Corasick自动机