字典树

在字典中我们可以查找字,字典树可以用来查找单词。
  • 假设单词全部由小写字母组成
  • 根节点不存储字母,设为空。children表示26种不同的子节点:单词首字母
  • 每个节点可以存储一个字母,一个children数组存储若干个子节点(最多26个)
    • 可以使用map or {},若有删除操作使用map更方便
  • 有相同前缀的单词公用前缀节点
  • 在单词结尾部分标记单词结束:使用一个单独的属性
优点:利用字符串的公共前缀来节约存储空间,最大限度地减少无谓的字符串比较,查询效率比哈希表高。

Trie树

  • JavaScript实现
    • 插入:就像是在查字典
      1. 从根节点开始
      2. 遍历插入单词,根据当前字母选择下一个节点
      + 下一个节点为空,map.set(letter, new Map()) or node[ch] = {}
      + node = node[letter]
      3. 单词遍历结束,isEnd属性设为true
    • 查找
      1. 每次从根节点开始
      2. 遍历输入的单词,根据当前字母选择下一个节点(map)
      3. 直到下一个节点不存在 -> 无此单词
      4. 单词遍历完毕,若查找前缀,直接返回true。否则,若当前节点的isEnd属性为真则此单词存在
//ES6
class Trie {
    constructor() {
        this.root = {};
    }

    insert(word) {
        let node = this.root;
        for (const ch of word) {
            if (!node[ch]) {
                node[ch] = {};
            }
            node = node[ch];
        }
        node.isEnd = true;//单词结束标记
    }

    searchPrefix(prefix) {
        let node = this.root;
        console.log("prefix:");
        for (const ch of prefix) {
            if (!node[ch]) {
                return false;
            }
			node = node[ch];//子节点
        }
        return node;
    }

    search(word) {
        let node = this.searchPrefix(word);
        if (node && node.isEnd) return true;
        return false;
    }
}
  • 删除单词
    • 若这个单词为其他单词的前缀,修改isEnd属性为false即可
    • 递归搜索到单词最后一个字母,回溯过程中在map中删除key,直到当前节点子数组长度Map.size > 1终止删除节点操作
原文地址:https://www.cnblogs.com/honey-cat/p/14657278.html