Trie 树的基本实现和特性

树和二叉搜索树

树 Tree

tree.png

二叉搜索树

二叉搜索树任何一个结点,它的左子树的所有结点都要小于这个根结点,它的右子树的所有结点都要大于根结点。

二叉树搜索树中序遍历是一个升序的序列。

二叉搜索树查找的效率更高。

binary_search_tree.png

Trie 树

基本结构

字典树,即 Trie 树,又称单词查找树或键树,是一种树形结构。
典型应用是用于统计和排序大量的字符串(不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。

Trie 树不是一颗二叉树,是多叉树。

优点:最大限度地减少无谓的字符串比较,查找效率比哈希表高。

trie.png

基本性质

  • 结点本身不存完整单词;
  • 从根结点到某一结点,路径上经过的字符连接起来,为该结点对应的字符串;
  • 每个结点的所有子结点路径代表的字符都不相同。

核心思想

Trie 树的核心思想就是空间换时间。

利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。

相关题目

二叉树的层次遍历

实现 Trie (前缀树)(亚马逊、微软、谷歌在半年内面试中考过)

单词搜索 II (亚马逊、微软、苹果在半年内面试中考过)

// 二叉树的层次遍历

/**
 * 广度优先搜索
 * @param {TreeNode} root
 * @return {number[][]}
 */
var levelOrder = function(root) {
  if (!root) return [];

  const ans = [];

  const queue = [root];

  while (queue.length) {
    let len = queue.length;

    ans.push([]);

    while (len--) {
      const n =  queue.shift();

      ans[ans.length - 1].push(n.val);

      n.left && queue.push(n.left);
      n.right && queue.push(n.right);
    }
  }

  return ans;
};
// 实现 Trie (前缀树)

var Trie = function() {
  this.children = {};
};

/** 
 * @param {string} word
 * @return {void}
 */
Trie.prototype.insert = function(word) {
  let nodes = this.children;

  for (const ch of word) {
    if (!nodes[ch]) {
      nodes[ch] = {};
    }
    nodes = nodes[ch];
  }

  nodes.isEnd = true;
};

Trie.prototype.searchPrefix = function(word) {
  let nodes = this.children;

  for (const ch of word) {
    if (!nodes[ch]) {
      return false;
    }
    nodes = nodes[ch];
  }

  return nodes;
};

/** 
 * @param {string} word
 * @return {boolean}
 */
Trie.prototype.search = function(word) {
  const nodes = this.searchPrefix(word);

  return nodes != undefined && nodes.isEnd !== undefined;
};

/** 
 * @param {string} prefix
 * @return {boolean}
 */
Trie.prototype.startsWith = function(prefix) {
  return this.searchPrefix(prefix);
};

/**
 * Your Trie object will be instantiated and called as such:
 * var obj = new Trie()
 * obj.insert(word)
 * var param_2 = obj.search(word)
 * var param_3 = obj.startsWith(prefix)
 */