1.字典树:
为字典设计的数据结构,专门处理字符串。
假如通讯录里面有很多人,要想快速查找的话,二分树以及各类排序算法实际上都不合适。
因此采用字典树结构
2.字典树结构:
字典树的节点不止一个,对于英语来说,每个节点有26个指向下面节点的指针,我们可以不用保留节点本身的值。
class Node{
private char val;
private Map<char, Node> next;
}
// 定义Node
但是对于进行遍历时,需要查看是否为单词,例如 pan / panda, 因此需要加入 isWord 判定在该节点时,是否为end。
// 定义 Node
class Node{
private isWord;
private Map<char, Node> next;
public Node(Boolean isWord){
this.isWord = isWord;
}
public Node(){
this(null);
}
}
3.具体实现
//实现字典树
public class Trie{
class Node{
private isWord;
private Map<char, Node> next;
public Node(Boolean isWord){
this.isWord = isWord;
next = new TreeMap<>();
}
public Node(){
this(null);
}
}
private Node root;
private int size;
public Trie(){
root = null;
size = 0;
}
// 添加单词
public void add(String word){
if(word == null) return false;
Node cur = root;
for(int i = 0; i < word.length(); i++){
char c = word.charAt(i);
if(cur.next.get(c) == null){
cur.next.put(c, new Node());
}
cur = cur.next.get(c);
}
if(!cur.isWord){
cur.isWord = true;
size++;
}
}
// 查询单词
public boolean has_word(String word){
if(word == null) return false;
Node cur = root;
for(int i = 0; i < word.length(); i++){
char c = word.charAt(i);
if(cur.next.get(c) == null){
return false;
}
cur = cur.next.get(c);
}
// 传入 panda 为单词,但是 Pan未传入,不能算作单词
return cur.isWord;
}
}
4.优化:添加前缀查询
public boolean isPrefix(String prefix){
if(prefix == null) return false;
Node cur = root;
for(int i = 0; i <prefix.length(); i++){
char c = prefix.charAt(i);
if(cur.next.get(c) == null){
return false;
}
cur = cur.next.get(c);
}
return true;
}
5.相关问题:
6.相关优化:
将每个节点不再只是一个字符,而是可以保存一个单词。
压缩字典树 / 字串查询 / 模式匹配问题