一、字典树
Trie,又称前缀树或字典树,是一种树形结构。该数据结构中,将Trie[26] 与英文26个字母一一对应,即Trie[0]代表字符a。
特点:字符串内存消耗小,字符串查询快
// 子节点
private Trie[] children;
// 是否结束
private boolean isEnd;
二、API
1、初始化 Trie
/**
* 初始化
*/
public Trie() {
// 英文字母26个,创建数组
children = new Trie[26];
// 节点默认为结束节点
isEnd = false;
}
2、插入
/**
* 插入数据
*
* @param word 插入数据
*/
public void insert(String word) {
// 获取根节点
Trie node = this;
// 根据遍历word中的字符
for (int i = 0; i < word.length(); i++) {
// 获取字符
char ch = word.charAt(i);
// 计算当前字符位置
int index = ch - 'a';
// 当子节点不存在时,即word没有存过,即创建子节点
if (node.children[index] == null) {
node.children[index] = new Trie();
}
// 子节点存在时,获取子节点
node = node.children[index];
}
// 插入后将子节点状态改为结束节点
node.isEnd = true;
}
3、查询
/**
* 查询字符串是否存在
*
* @param word 字符串
* @return 存在返回true, 反之返回false
*/
public boolean search(String word) {
// 调用查询前缀方法,返回末尾字符节点
Trie node = searchPrefix(word);
// 末尾字符所在节点不为空,且节点状态为结束节点时,说明字符串已存在
return node != null && node.isEnd;
}
/**
* 查询字符前缀是否存在
*
* @param prefix 字符串前缀
* @return 存在时返回字符前缀末尾节点,不存在则返回null
*/
private Trie searchPrefix(String prefix) {
// 获取根节点
Trie node = this;
// 根据遍历word中的字符
for (int i = 0; i < prefix.length(); i++) {
// 获取字符
char ch = prefix.charAt(i);
// 计算字符位置
int index = ch - 'a';
// 字符节点不存在时返回null
if (node.children[index] == null) {
return null;
}
// 字符节点存在时,获取子节点
node = node.children[index];
}
return node;
}
4、查询字符串前缀
/**
* 查询字符前缀是否存在
*
* @param prefix 字符串前缀
* @return 存在返回true,反之返回false
*/
public boolean startsWith(String prefix) {
return searchPrefix(prefix) != null;
}
/**
* 查询字符前缀是否存在
*
* @param prefix 字符串前缀
* @return 存在时返回字符前缀末尾节点,不存在则返回null
*/
private Trie searchPrefix(String prefix) {
// 获取根节点
Trie node = this;
// 根据遍历word中的字符
for (int i = 0; i < prefix.length(); i++) {
// 获取字符
char ch = prefix.charAt(i);
// 计算字符位置
int index = ch - 'a';
// 字符节点不存在时返回null
if (node.children[index] == null) {
return null;
}
// 字符节点存在时,获取子节点
node = node.children[index];
}
return node;
}