Trie树:字典树,单词查找树
特点:
- 根节点不包含元素;
- 将根到当前节点路径上的字符连接起来,即为该节点对应的字符串;
- 每个节点的子节点对应的字符串各不相同;
- 对n个字符串构建字典树,时间复杂度为O(n*len),len表示字符串的平均长度;
- 对字典树查找的时间复杂度为O(len),len为待查找字符串的长度;
- 以空间换时间。
应用:
- 在n个字符串中,判断是否存在某个字符串是另一个字符串的前缀;
- 对n个正整数,求出异或值最大的两个数。
import java.util.Scanner;
class TrieNode{
TrieNode[] next = new TrieNode[26]; //假设字典树中只存在英文小写字母
boolean flag = false; //标志从根到当前节点的字符连接起来是否构成一个合乎条件的单词
}
public class Trie {
TrieNode root = new TrieNode(); //字典树根节点(哨兵)
public boolean searchTrie(String str) { //搜索字符串是否出现在字典树中
if (str == null || str.length() == 0 || root == null)
return false;
int i = 0;
TrieNode p = root;
while (i < str.length()) {
char temp = str.charAt(i);
TrieNode t = p.next[temp - 'a'];
if (t == null)
return false;
p = t;
i++;
}
if (p.flag == true)
return true;
return false;
}
public void insertTrie(String str) { //将字符串插入字典树
insertTrie2(str, 0, root);
}
public void insertTrie2(String str, int i, TrieNode root) {
if (str == null || str.length() == 0)
return;
if (i >= str.length()) {
root.flag = true;
return;
}
char temp = str.charAt(i);
if (root.next[temp - 'a'] != null) {
if (i >= str.length())
root.flag = true;
return;
}
TrieNode t = new TrieNode();
root.next[temp - 'a'] = t;
insertTrie2(str, i + 1, t);
}
public static void main(String[] args) {
Trie trie = new Trie();
String[] strs = new String[5];
strs[0] = "hello";
strs[1] = "world";
strs[2] = "dengzy";
strs[3] = "jlu";
strs[4] = "nicetomeetyou";
for (int i = 0; i < 5; i++)
trie.insertTrie(strs[i]);
Scanner in = new Scanner(System.in);
while (true) {
String str = in.next();
System.out.println(trie.searchTrie(str));
}
}
}