基本结构

image.png

基本性质

image.png

内部实现

image.png

  • 以下是一颗插入过adc、da、dda这三个单次的数组实现的字典树

image.png

  • Trie树的核心思想是空间换时间,无论是保存树的结构、字符集数组还是字符集映射,都需要额外的空间
  • 利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的
  • 分组思想-前缀相同的字符串在同一子树中

    实战

    208. 实现 Trie (前缀树)

    Trie(发音类似 “try”)或者说 前缀树 是一种树形数据结构,用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景,例如自动补完和拼写检查。 请你实现 Trie 类: Trie() 初始化前缀树对象。 void insert(String word) 向前缀树中插入字符串 word 。 boolean search(String word) 如果字符串 word 在前缀树中,返回 true(即,在检索之前已经插入);否则,返回 false 。 boolean startsWith(String prefix) 如果之前已经插入的字符串 word 的前缀之一为 prefix ,返回 true ;否则,返回 false 。

  1. // 实现 Trie (前缀树):以下三种操作的时间复杂度都是O(n)
  2. class Trie {
  3. class TrieNode {
  4. TrieNode child[]; // 前缀树的节点可能有26个子节点
  5. boolean isWorld; // 到达该节点的路径对应的字符串是否为字典中的完整单词
  6. TrieNode() {
  7. child = new TrieNode[26];
  8. }
  9. }
  10. private TrieNode root;
  11. public Trie() {
  12. root = new TrieNode();
  13. }
  14. public void insert(String word) {
  15. // 1. 首先前往前缀树的根节点
  16. TrieNode node = root;
  17. // 2. 确定该根节点是否存在一个子节点与第一个字符对应,如果存在则前往,如果不存在则添加后前往
  18. for (char ch : word.toCharArray()) {
  19. if (node.child[ch - 'a'] == null) {
  20. node.child[ch - 'a'] = new TrieNode();
  21. }
  22. // 3. 以此类推将字符串中的其他字符添加到前缀树中
  23. node = node.child[ch - 'a'];
  24. }
  25. // 4. 全部添加进去后,将最后一个节点的标识设置为true
  26. node.isWorld = true;
  27. }
  28. // 思路和insert类似
  29. public boolean search(String word) {
  30. // 1. 从根节点开始查找,如果子节点没有与字符相等,返回false,否则继续往下查找,直到最后一个字符
  31. TrieNode node = root;
  32. for (char ch : word.toCharArray()) {
  33. if (node.child[ch - 'a'] == null) {
  34. return false;
  35. }
  36. node = node.child[ch - 'a'];
  37. }
  38. return node.isWorld;
  39. }
  40. public boolean startsWith(String prefix) {
  41. TrieNode node = root;
  42. for (char ch : prefix.toCharArray()) {
  43. if (node.child[ch - 'a'] == null) {
  44. return false;
  45. }
  46. node = node.child[ch - 'a'];
  47. }
  48. // 能查完prefix的全部字符,说明一定startsWith
  49. return true;
  50. }
  51. }