Trie 树

2018-12-18  本文已影响0人  币来币往

Trie树,也叫字典树,它是一种专门处理字符串匹配的数据结构,用来解决在一组字符串集合中快速查找某个字符串的问题。
Trie树的核心思想就是,将几个字符串的公共前缀合并在一起。
例如 how, hi, hello, her, so, see几个单词构成的trie树如下:

image.png
其中,跟节点不包含任何信息,每个节点包含字符串中的一个字符,红色节点表示是一个单词的结尾。
当我们要查找一个字符串时,从根节点依次往下匹配即可,例如查找单词her,我们先匹配h,然后接着找到e,再往下找到r; 如果我们那he去匹配呢,此时匹配结束的终点e不是红色,表示不是一个单词,它只是某个单词的一部分,所以匹配失败。

Trie树的存储

这里我们假设单词都是由26个小写字母构成,这样我们就可以用下面的结构来存储trieNode。它的子节点指针存储在对应的数组元素中,如a存储在第0个下标,z存储在第25个下标内。

class TrieNode{
    char data;
    TrieNode[] children = new TrieNode[26];
}

public class Trie {
    private TrieNode root = new TrieNode('/');

    public void insert(char[] text){
        if(text == null || text.length == 0) return;
        TrieNode p = root;
        for(int i = 0; i < text.length; i++){
            TrieNode newNode = new TrieNode(text[i]);

            if(p.children[text[i] - 'a'] == null){
                p.children[text[i] - 'a'] = newNode;
            }
            p = p.children[text[i] - 'a'];
        }
        p.isEndingChar = true;
    }

    public boolean find(char[] text){
        TrieNode p = root;
        for(int i = 0; i < text.length; i++){
            int index = text[i] - 'a';
            if(p.children[index] == null){
                return false;
            }
            p = p.children[index];
        }
        return p.isEndingChar;
    }
}

上面是一个trie树的实现,通过观察我们发现,它其实是很耗内存的,因为每个节点都有一个长度为26的数组,如果我们再考虑上大写字母,数组等符合,将会需要一个更大的数组。
所以Trie树其实并不被用来做精确匹配,而是常被用来做查找前缀匹配的字符串,其中最常用的一个功能就是搜索关键词的提升功能。


image.png
上一篇下一篇

猜你喜欢

热点阅读