字典树(Trie树)的应用
字典树的定义
字典树,又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。
字典树的用处
说完了字典树的定义之后,我们来了解一下大名鼎鼎的字典树能用来解决什么问题,请大家先想一下如果我们想要实现这样一个功能:插入大量字符串,然后查找某些字符串是否在刚才插入的字符串序列中。我想大部分同学首先想到的就是用一个哈希表来存储之前插入的字符串,然后再在之前的哈希表里面查找是否存在就行了。这种方法固然可行,但如果插入的字符串数量特别庞大的话,这样的算法的时间复杂度就会特别高,而且如果要找的是某字符串的前缀,这个算法就会变得更加复杂。为了用更少的空间来实现这一问题,我们可以用一种更简洁的方法——字典树。字典树就是为这种问题而生的,它是一种专门处理字符串匹配的数据结构,用来解决在一组字符串集合中快速查找某个字符串的问题。
字典树的核心思想
字典树的核心思想就是通过最大限度地减少无谓的字符串比较,使得查询高效率,即【用空间换时间】,再利用共同前缀来提高查询效率。
字典树的特点
1、 根节点不包含字符,除根节点外每个节点都只包含一个字符
2、 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串
3、 每个节点的所有子节点包含的字符都不相同
字典树的基本操作
插入、查找、删除(不常用)。
字典树的代码实现(JAVA)
class Trie {
private Trie[] children;
private boolean isEnd;
/** Initialize your data structure here. */
public Trie() {
children = new Trie[26];
isEnd = false;
}
/** Inserts a word into the trie. */
public void insert(String word) {
Trie node = this;
for( int i = 0; i < word.length(); ++i ){
int index = word.charAt(i) - 'a';
if( node.children[index] == null ){
node.children[index] = new Trie();
}
node = node.children[index];
}
node.isEnd = true;
}
/** Returns if the word is in the trie. */
public boolean search(String word) {
Trie node = searchPrefix(word);
return node != null && node.isEnd;
}
/** Returns if there is any word in the trie that starts with the given prefix. */
public boolean startsWith(String prefix) {
Trie node = searchPrefix(prefix);
return node != null;
}
/** search prefix */
public Trie searchPrefix(String prefix){
Trie node = this;
for( int i = 0; i < prefix.length(); ++i ){
int index = prefix.charAt(i) - 'a';
if( node.children[index] == null ){
return null;
}
node = node.children[index];
}
return node;
}
}
/**
* Your Trie object will be instantiated and called as such:
* Trie obj = new Trie();
* obj.insert(word);
* boolean param_2 = obj.search(word);
* boolean param_3 = obj.startsWith(prefix);
*/
字典树的应用
字典树可以高效地解决以下问题:
串的快速检索、串排序、最长公共前缀