5.前缀树

85 阅读1分钟
// 前缀树
class PreTree{
  constructor(words=[]) {
    this.pass = 0 // 有多少字符经过该节点
    this.end = 0 // 有多少字符以该节点作为结点
    this.nexts = new Map() // 子节点哈希表
    for(let i in words) this.insert(words[i])
  }
  insert(word) { // 插入
    if (!word) return 
    let cur = this
    cur.pass++
    for (let s of word) {
      if (!cur.nexts.get(s)) {
        cur.nexts.set(s, new PreTree())
      }
      cur = cur.nexts.get(s)
      cur.pass++
    }
    cur.end++
  }
  delete(word) { // 删除
    if (this.search(word)>0) {
      let cur = this
      cur.pass--
      for (let s of word) {
        if(--cur.nexts.get(s).pass==0) return cur.nexts.delete(s)
        cur = cur.nexts.get(s)
      }
      cur.end--
    }
  }
  search(word) { // 查询字符串加入过几次
    if (!word) return 0
    let cur = this
    for (let s of word) {
      if (!cur.nexts.has(s)) return 0
      cur = cur.nexts.get(s)
    }
    return cur.end
  }
  prefixNumber(pre) { // 前缀查询
    if (!pre) return 
    let cur = this 
    for (let s of pre) {
      if (!cur.nexts.has(s)) return 0
      cur = cur.nexts.get(s)
    }
    return cur.pass
  }
}