前缀树即Trie,也称作字典树,主要应用于通讯录和字典中单词的查找等,是一种比较综合性的数据结构,这里只是简单的实现一部分功能,包括插入一个单词和查找字典里有没有这个单词等.字典树的查找操作的时间复杂度与字典的数量无关,只与自己要查找的那个单词的长度有关,这样就使字典树在超大量的数据查找中具有相当大的优势,理论上对于一个英语单词,不考虑大写的情况下,从根节点开始,每个节点应当可以最多拥有26个孩子节点,但是实际操作中并不是这样的,而是可以采取一种比较巧妙的办法:就是用一个集合Map来存储一个节点的所有下一个节点,因此对于任意一个节点,应当由两个部分组成,包括一个char类型的值和一个TreeMap类型的键值对,其中key应为某一个孩子节点的char类型的值,而value为对应的那个Node类型的节点.对于前缀树的操作的描述见代码中的注释.
代码如下:
import java.util.TreeMap;
/**
* 前缀树的实现
* @author ChenZhuJi
*
*/
public class Trie {
private class Node {
public boolean isWord;
public TreeMap<Character, Node> next;
public Node(boolean isWord) {
this.isWord = isWord;
next = new TreeMap<Character, Trie.Node>();
}
public Node() {
this(false);
}
}
private Node root; //根节点
private int size;
public Trie() {
root = new Node();
size = 0;
}
public int getSize() {
return size;
}
/**
* 向Tire中添加一个新的单词
* @param word 新单词
*/
public void add(String word) {
Node cur = root;
for(int i = 0; i < word.length(); i++) {
char c = word.charAt(i); //获取要添加单词的每一个字母
if(cur.next.get(c) == null ) { //若这个字母在cur的next所代表的映射中不存在
cur.next.put(c, new Node()); //就把这个字母添加到cur的next所代表的映射中
}
cur = cur.next.get(c); //cur指向下一个字母或添加字母完成后的那个字母
}
if( !cur.isWord ) { //此时添加结束,必须看看之前这个单词存不存在,如果不存在才让size++
cur.isWord = true;
size++;
}
}
/**
* 查询字典树中是否包含某个单词
* @param word 待查找的单词
* @return 是否存在
*/
public boolean contains(String word) {
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);
}
return cur.isWord;
}
/**
* 查询字典树中是否存在单词以prefix为前缀
* @param prefix 前缀
* @return true/false
*/
public boolean isPrefix(String prefix) {
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;
}
}