Trie 前缀树
基础与数据结构
说明
按字符逐层共享前缀;插入和查询耗时与单词长度成正比。
分析
从根到节点的路径对应一个字符串前缀,相同前缀只存储一次。Insert 缺少边时创建新节点,Has 逐字符跟随边并检查结束标记。
只插入gopher时,go的路径存在却不是词尾,因此Has(go)为false。插入go只需给已有o节点设结束标记。rune表示Unicode码点,不自动完成大小写折叠或Unicode规范化。
查看图表代码
适用前提与边界
它适合前缀检索;字符集很大时,节点中的映射和指针会带来明显内存开销。 空字符串会把根标记为词尾;示例按rune比较,不进行大小写或Unicode规范化,业务需先统一文本规则。
示例输入与调用
go
trie := new(Trie)
trie.Insert("gopher")
fmt.Println(trie.Has("gopher"), trie.Has("go"))运行输出
text
true false完整 Go 示例
go
package main
import "fmt"
type Trie struct {
next map[rune]*Trie
end bool
}
func (t *Trie) Insert(s string) {
for _, r := range s {
if t.next == nil {
t.next = map[rune]*Trie{}
}
if t.next[r] == nil {
t.next[r] = &Trie{}
}
t = t.next[r]
}
t.end = true
}
func (t *Trie) Has(s string) bool {
for _, r := range s {
t = t.next[r]
if t == nil {
return false
}
}
return t.end
}
func main() {
trie := new(Trie)
trie.Insert("gopher")
fmt.Println(trie.Has("gopher"), trie.Has("go"))
}继续阅读
- 系统学习
- 系统学习
- 系统学习