Java数据结构---Trie(字典树/前缀树)
1. Trie简介
前缀树是一种树形结构,在百度中查找一个单词,通常搜索前几个字母,百度就会自动提示后面的字母,即搜索提示,这是前缀树的一个最典型的应用。
2. 该数据结构的节点的构建
前缀树的结点包含属性isWord和指向孩子节点的指针children,它是一个数组。
完整的定义:
class TrieNode {
// 该节点的属性---isWord,它是一个标签,用来表示是否是一个完整的单词
boolean isWord;
// 定义该节点的孩子节点,用一个长度为26的TrieNode[]数组来存储指向下一个孩子节点的指针
TrieNode[] children;
public TrieNode {
// 默认isWord标签为false
isWord = false;
// 默认孩子节点有26个(英文字母有26个),用一个长度为26的TrieNode[]数组来存储孩子节点的指针
children = new TrieNode[26];
}
}
可以简写成如下形式:
class TrieNode {
boolean isWord;
TrieNode[] children = new TrieNode[26];
}
3. 前缀树的构建
// 定义前缀树的节点
class TrieNode {
boolean isWord;
TrieNode[] children = new TrieNode[26];
}
// 定义前缀树
class Trie {
TrieNode root;
public Trie() {
// 构造一个空的节点作为根节点
root = new TrieNode();
}
4. 基础操作(增、查)
- 增 insert()
public void insert(String word) {
TrieNode cur = root;
for (int i = 0; i < word.length(); i++) {
// c为要保存字符的ASCII码值
int c = word.charAt(i) - 'a';
// 如果当前节点的值为c的孩子节点不存在,则新建该孩子节点并指向它
if (cur.children[c] == null) {
cur.children[c] = new TrieNode();
}
// 如果当前节点的值为c的孩子节点存在,则cur指向该孩子节点
cur = cur.children[c];
}
// 当所有节点都遍历完成,将当前节点,即最后一个节点的标识符isWord置为true,表示从根节点遍历到该节点的字母组成了一个单词
cur.isWord = true;
}
- 完整查找 search():给定一个完整的单词,在前缀树中查找它是否存在
思路:如果在遍历过程中发现字母有缺失(cur.children[c] == null),即下一个字母查找为null,则返回false,表示前缀树种不存在这个单词。如果遍历完成,就要判断此时cur是否为单词末尾:如果是,返回true;如果不是,说明word仅仅是一个前缀,并不完整,返回false
public boolean search(String word){
TrieNode cur = root;
for(int i = 0;i < word.length(); i++){
int c = word.charAt(i)-'a';
if(cur.children[c] == null) return false;
cur = cur.children[c];
}
return cur.isWord;
}
- 按前缀查找 startsWith()
思路:与完整查找类似,区别在于不需要判断最后一个节点是否是isWord
public boolean search(String word){
TrieNode cur = root;
for(int i = 0;i < word.length(); i++){
int c = word.charAt(i)-'a';
if(cur.children[c] == null) return false;
cur = cur.children[c];
}
return true;
}