字典树(前缀树)Trie
目标:
- 认识Trie
- Trie的实现
- 查询
- 前缀查询
- 模式匹配
- Trie和字符串的映射
1.1 认识Trie
查询每个条目的时间复杂度,和字典中一共有多少条目无关。时间复杂度为O(w),w为查询单词的长度。
字典:如果有n个条目,使用树结构,查询的时间复杂度为O(logn),如果有100万个条目(2^20^),logn大约是20。
Trie的结构图:
将整个字符串以字母为单位进行拆开,从根节点开始一直到叶子节点,去遍历,每遍历到一个叶子节点,就形成一个单词。
每个节点有若干指向下个节点的指针。
有些单词是某些单词的前缀,所以每一个node需要一个标识:是否是单词的结尾。
1.2 Trie的实现
boolean isWord;
Map<Character, Node> next;
-
添加元素:
添加一个字符串,然后拆为一个个字符,将这些字符装填进树中,作为节点。
// Trie中添加新的单词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.put(c, new Node()); } cur = cur.next.get(c); } if (!cur.isWord) { cur.isWord = true; size++; } }
-
查询元素:
// Trie字典树的查询 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; }
-
前缀搜索
// 查询是否在Trie中有单词以prefix为前缀 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; }
-