Trie树,即字典树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高。小写英文字母或大写英文字母的字典数是一个26叉树。Trie树的根结点是不保存数据的,所有的数据都保存在它的孩子节点中。
字符串go, golang, php, python, perl,它这棵Trie树可如下图所示构造:
Trie的核心思想是空间换时间。利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。
基本性质
- 根节点不包含字符,除根节点外每一个节点都只包含一个字符。
- 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。
- 每个节点的所有子节点包含的字符都不相同。
code
package mainimport "fmt"type Trie struct {// 自身节点 与 若干个子节点Children map[byte]*Trie// 标识节点是否是一个单词最后的一个字符IsWord bool}func NewTrie() *Trie {return &Trie{}}func (t *Trie) Add(word string) {cur := t// 遍历 word的每一个字符for _, c := range []byte(word) {if cur.Children == nil {cur.Children = make(map[byte]*Trie)}// 查找子节点中是否包含当前字符// 如果不包含, 添加一下if _, ok := cur.Children[c]; !ok {cur.Children[c] = NewTrie()}// cur 指向子节点cur = cur.Children[c]}// 将最后一个节点字符的 尾设置为 truecur.IsWord = true}func (t *Trie) Search(word string) bool {cur := t// 遍历 word的每一个字符for _, c := range []byte(word) {// 查找子节点中是否包含当前字符if _, ok := cur.Children[c]; !ok {return false}// cur 指向下一个子节点cur = cur.Children[c]}// 判断最后一个单词是否是 单词末尾 cur.isWord == true,// 直接缩写为 cur.isWordreturn cur.IsWord}func (t *Trie) StartsWith(prefix string) bool {cur := t// 遍历 word的每一个字符for _, c := range []byte(prefix) {// 查找子节点中是否包含当前字符if _, ok := cur.Children[c]; !ok {return false}// cur 指向下一个子节点cur = cur.Children[c]}return true}func main() {// 创建字典树t := NewTrie()t.Add("door")// 测试fmt.Println(t.Search("dog"))fmt.Println(t.Search("door"))fmt.Println(t.StartsWith("do"))}
