定义

Trie,又称前缀树或字典树,是一棵有根树,其每个节点包含以下字段:

  • 指向子节点的指针数组 children。数组长度为 26,即小写英文字母的数量。此时 children[0] 对应小写字母 a,children[1] 对应小写字母 b,…,children[25] 对应小写字母 z。
  • 布尔字段 isEnd,表示该节点是否为字符串的结尾

典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高。

前缀树的核心思想是空间换时间。利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。

给出一组单词,inn, int, at, age, adv,ant, adv 我们可以得到下面的Trie:
image.png

题目:208. 实现 Trie (前缀树) - 力扣(LeetCode)

A trie (pronounced as “try”) or prefix tree is a tree data structure used to efficiently store and retrieve keys in a dataset of strings. There are various applications of this data structure, such as autocomplete and spellchecker.

Implement the Trie class:

  • Trie() Initializes the trie object.
  • void insert(String word) Inserts the string word into the trie.
  • boolean search(String word) Returns true if the string word is in the trie (i.e., was inserted before), and false otherwise.
  • boolean startsWith(String prefix) Returns true if there is a previously inserted string word that has the prefix prefix, and false otherwise.

(实现代码写的比较粗糙……看个意思就行)

HashMap实现

  1. class Trie {
  2. public String value;
  3. public Map<Character, Trie> children;
  4. public boolean isEnd;
  5. public Trie() {
  6. this.value = null;
  7. this.isEnd = false;
  8. this.children = new HashMap<>();
  9. }
  10. public void insert(String word) {
  11. if (search(word)) return;
  12. char []str = word.toCharArray();
  13. int len = str.length;
  14. int i;
  15. Trie currentTrie = new Trie();
  16. Map<Character, Trie> ths = this.children;
  17. for (i = 0; i < len; i++){
  18. if (ths.containsKey(str[i])) {
  19. currentTrie = ths.get(str[i]);
  20. ths = ths.get(str[i]).children;
  21. }
  22. else {
  23. Trie newTire = new Trie();
  24. ths.put(str[i], newTire);
  25. ths = newTire.children;
  26. if (i == len - 1){
  27. newTire.value = word;
  28. newTire.isEnd = true;
  29. return;
  30. }
  31. }
  32. }
  33. if (!currentTrie.isEnd) currentTrie.value = word;
  34. }
  35. public boolean search(String word) {
  36. if (find(word) != null) return true;
  37. return false;
  38. }
  39. private String find (String word){
  40. char []str = word.toCharArray();
  41. int len = str.length;
  42. int i;
  43. String res = null;
  44. Map<Character, Trie> ths = this.children;
  45. for (i = 0; i < len; i++){
  46. if (ths.containsKey(str[i])) {
  47. res = ths.get(str[i]).value;
  48. ths = ths.get(str[i]).children;
  49. }
  50. else break;
  51. }
  52. if (i != len) res = null;
  53. return res;
  54. }
  55. public boolean startsWith(String prefix) {
  56. char []str = prefix.toCharArray();
  57. int len = str.length;
  58. int i;
  59. Map<Character, Trie> ths = this.children;
  60. for (i = 0; i < len; i++){
  61. if (ths.containsKey(str[i])) {
  62. ths = ths.get(str[i]).children;
  63. }
  64. else break;
  65. }
  66. if (i == len) return true;
  67. return false;
  68. }
  69. }
  70. /**
  71. * Your Trie object will be instantiated and called as such:
  72. * Trie obj = new Trie();
  73. * obj.insert(word);
  74. * boolean param_2 = obj.search(word);
  75. * boolean param_3 = obj.startsWith(prefix);
  76. */

数组实现

  1. class Trie {
  2. public String value;
  3. public Trie[] nodes;
  4. public boolean isEnd;
  5. public Trie() {
  6. this.nodes = new Trie[26];
  7. this.value = null;
  8. this.isEnd = false;
  9. }
  10. public void insert(String word) {
  11. char[] str = word.toCharArray();
  12. Trie currentTrie = this;
  13. for (char c : str){
  14. if (currentTrie.nodes[c-'a'] == null) currentTrie.nodes[c-'a'] = new Trie();
  15. currentTrie = currentTrie.nodes[c-'a'];
  16. }
  17. currentTrie.isEnd = true;
  18. currentTrie.value = word;
  19. }
  20. public boolean search(String word) {
  21. char[] str = word.toCharArray();
  22. Trie currentTrie = this;
  23. for (char c : str){
  24. if (currentTrie.nodes[c-'a'] == null) return false;
  25. currentTrie = currentTrie.nodes[c-'a'];
  26. }
  27. return currentTrie.isEnd;
  28. }
  29. public boolean startsWith(String prefix) {
  30. char[] str = prefix.toCharArray();
  31. Trie currentTrie = this;
  32. for (char c : str){
  33. if (currentTrie.nodes[c-'a'] == null) return false;
  34. currentTrie = currentTrie.nodes[c-'a'];
  35. }
  36. return true;
  37. }
  38. }
  39. /**
  40. * Your Trie object will be instantiated and called as such:
  41. * Trie obj = new Trie();
  42. * obj.insert(word);
  43. * boolean param_2 = obj.search(word);
  44. * boolean param_3 = obj.startsWith(prefix);
  45. */