使用HashMap实现前缀树
什么是前缀树
前缀树Trie Tree,是一种字典树,匹配树。
①根节点不包含字符,除根节点外的每一个子节点都包含一个字符。
②从根节点到某一个节点,路径上经过的字符连接起来,为该节点对应的字符串。
③每个节点的所有子节点包含的字符互不相同。
④从第一字符开始有连续重复的字符只占用一个节点,比如上面的to,和ten,中重复的单词t只占用了一个节点。
前缀树的作用
- 字符串是否前缀匹配:
1.1 当前字符串的前缀在字典中已经存在
1.2 当前字符串在字典中是其他字符串的前缀 - 字典是否包含当前字符串
- 词频统计
- 字符串排序
使用HashMap实现前缀树
import java.util.HashMap;
/**
* java实现前缀树
*/
public class TrieTree {
private class Node {
public HashMap<Character , Node> childs; //子结点
public boolean isLeaf; //当前结点是否是完整字符串(是否是叶结点)
public Node () {
this.isLeaf = false;
this.childs = new HashMap<>();
}
}
//根结点
private Node root;
public TrieTree () {
root = new Node();
}
/** Inserts a word into the trie. */
public void insert (String str) {
insert(root , str);
}
//添加结点的过程既是添加结点的作用也是匹配前缀的过程
private void insert (Node root , String str) {
if (str == null || str.length() == 0) return;
char[] chars = str.toCharArray();
Node cur = root;
for (int i = 0 , length = chars.length ; i < length ; i++) {
//不包含当前字符加入
if (! cur.childs.containsKey(chars[i])) {
cur.childs.put(chars[i] , new Node());
}
cur = cur.childs.get(chars[i]);
}
if (!cur.isLeaf)
cur.isLeaf = true;
}
/** Returns if the word is in the trie. */
public boolean search (String str) {
return search(root , str);
}
//遍历查找是否包含字符串
private boolean search (Node root , String str) {
if (str == null || str.length() == 0) return false;
char[] chars = str.toCharArray();
Node cur = root;
for (int i = 0 , length = chars.length ; i < length ; i++) {
if (!cur.childs.containsKey(chars[i])) {
return false;
}
cur = cur.childs.get(chars[i]);
}
return cur.isLeaf;
}
/** Returns if there is any word in the trie that starts with the given prefix. */
public boolean startsWith(String str) {
if (str == null || str.length() == 0) return false;
char[] chars = str.toCharArray();
Node cur = root;
for (int i = 0 , length = chars.length ; i < length ; i++) {
if (!cur.childs.containsKey(chars[i]))
return false;
cur = cur.childs.get(chars[i]);
}
return true;
}
}