前缀树实现

135 阅读2分钟

就相当于多叉树嘛。26个字母。根节点我们默认空,然后下面分出来26个子节点。。

当插入单词的时候,两种情况:1.字母存在,那么node = node.next[字母] ,但是我们并不在意这个节点存的啥,只要它存在就行。 2.字母不存在,那么就给他赋值一个结构体。 当最后全部出入完毕的时候给node.isend赋值true

查询的时候也是两种情况:1.字母不存在就是node.next【字母】==nil,直接可以返回nil 2.存在不为空的时候,遍历下一个执指针走到node = node.next[字母]

在真正查询单词在不在的时候,要注意isend条件,只有上一个函数返回不空并且end为true的时候,单词才真的在前缀树里。


type Trie struct {
   //相当于下边练了26个分支
   next [26]*Trie
   isEnd    bool
}


func Constructor6() Trie {
   return Trie{}
}

//我们从字典树的根开始,插入字符串。对于当前字符对应的子节点,有两种情况:
//
//子节点存在。沿着指针移动到子节点,继续处理下一个字符。
//子节点不存在。创建一个新的子节点,记录在 \textit{children}children 数组的对应位置上,然后沿着指针移动到子节点,继续搜索下一个字符。
//
func (this *Trie) Insert(word string)  {
   node := this
   for _,ch :=range word{
      ch -= 'a'
      if node.next[ch] == nil{
         node.next[ch] = &Trie{}
      }

      node = node.next[ch]
   }
   node.isEnd = true

}


func (this *Trie) Search(word string) bool {
   node := this.SearchPrefix(word)
   return node != nil && node.isEnd
}

func (this *Trie) StartsWith(prefix string) bool {
   return this.SearchPrefix(prefix) != nil
}
//我们从字典树的根开始,查找前缀。对于当前字符对应的子节点,有两种情况:
//
//子节点存在。沿着指针移动到子节点,继续搜索下一个字符。
//子节点不存在。说明字典树中不包含该前缀,返回空指针。

//若搜索到了前缀的末尾,就说明字典树中存在该前缀。
//此外,若前缀末尾对应节点的 isEnd 为真,则说明字典树中存在该字符串。

func (this *Trie) SearchPrefix(prefix string) *Trie {
   node := this
   for _, ch := range prefix {
      ch -= 'a'
      if node.next[ch] == nil {
         return nil
      }
      node = node.next[ch]
   }
   return node
}