一、介绍
trie树一般读作/ˈtraɪ/ "try"树,又称“字典树”或”前缀树“,“单词查找树”或“键树”,可以应用于搜索提示,当输入一个搜索关键字,可以根据前缀返回最相似的或者完全匹配的结果。 其他的应用有:字符串检索、词频统计、字符串排序、前缀匹配等。
二、实现
trie树,顾名思义是一种树形的结构,那么,我们就先来看一下组成trie树的树节点应该如何定义:
class TrieNode {
public int path;//这个节点所在字符路径上,有多少个单词用到了当前的节点
public int end;// 有多少单词是以当前节点为结尾的
public TrieNode[] nexts;// 下一层级的节点引用
public TrieNode() {
path = 0;
end = 0;
nexts = new TrieNode[26];
}
}
一个完整的trie结构,有几个基本的操作api,我们逐一了解他们的作用:
public class Trie {
private TrieNode root;
public Trie() {
root = new TrieNode();
}
// 插入单词到trie结构中
public void insert(String word) {
if (word == null) {
return;
}
char[] chs = word.toCharArray();
TrieNode node = root;
int index;
for (int i = 0; i < chs.length; i++) {
index = chs[i] - 'a';
if (node.nexts[index] == null) {
node.nexts[index] = new TrieNode();
}
node = node.nexts[index];
node.path++;
}
node.end++;
}
// 查询单词是否在结构中存在
public int search(String word) {
if (word == null) {
return 0;
}
char[] chs = word.toCharArray();
TrieNode node = root;
int index = 0;
for (int i = 0; i < chs.length; i++) {
index = chs[i] - 'a';
if (node.nexts[index] == null) {
return 0;
}
node = node.nexts[index];
}
return node.end;
}
// 返回以pre做为前缀的单词的数量
public int prefix(String pre) {
if (pre == null) {
return 0;
}
char[] chs = pre.toCharArray();
TrieNode node = root;
int index = 0;
for (int i = 0; i < chs.length; i++) {
index = chs[i] - 'a';
if (node.nexts[index] == null) {
return 0;
}
node = node.nexts[index];
}
return node.path;
}
// 在结构中删除一个单词
public void delete(String word) {
if (search(word) != 0) {
char[] chs = word.toCharArray();
TrieNode node = root;
int index = 0;
for (int i = 0; i < chs.length; i++) {
index = chs[i] - 'a';
if (--node.nexts[index].path == 0) {
node.nexts[index] = null;
return;
}
node = node.nexts[index];
}
node.end--;
}
}
}