Go-字典树的实现

介绍

Trie(字典树)是一种用于高效存储和查找字符串的数据结构。

Go语言标准库中没有提供Trie树的实现,但是可以使用第三方包来实现Trie树。


 

下面是Trie的使用方法:

  1. 创建Trie树:首先需要创建一个Trie树的根节点,根节点不存储任何字符,只是作为一个起始点。

  2. 插入字符串:将字符串中的每个字符依次插入到Trie树中。从根节点开始,如果当前字符在子节点中不存在,则创建一个新的子节点,并将当前字符存储在该子节点中。如果当前字符在子节点中已经存在,则直接进入该子节点。

  3. 查找字符串:从根节点开始,依次查找字符串中的每个字符,如果在子节点中找到了该字符,则进入该子节点继续查找下一个字符。如果在子节点中没有找到该字符,则说明该字符串不存在于Trie树中。

  4. 删除字符串:从根节点开始,依次查找字符串中的每个字符,如果在子节点中找到了该字符,则进入该子节点继续查找下一个字符。如果在子节点中没有找到该字符,则说明该字符串不存在于Trie树中,无需删除。如果找到了该字符串的最后一个字符,需要将该节点标记为“结束节点”,表示该节点是一个字符串的结尾。如果该节点没有其他子节点,则可以直接删除该节点。

Trie树的优点是可以快速地查找和插入字符串,时间复杂度为O(k),其中k是字符串的长度。但是Trie树的缺点是空间复杂度较高,因为每个节点都需要存储一个字符和若干个子节点的指针。


 

代码实现

下面是一个简单的Trie树的实现示例,包括创建Trie树、插入字符串、查找字符串和删除字符串的操作:

package main

import "fmt"

type TrieNode struct {
    children map[rune]*TrieNode
    isEnd    bool
}

type Trie struct {
    root *TrieNode
}

func NewTrie() *Trie {
    return &Trie{root: &TrieNode{children: make(map[rune]*TrieNode)}}
}

func (t *Trie) Insert(word string) {
    node := t.root
    for _, c := range word {
        if _, ok := node.children[c]; !ok {
            node.children[c] = &TrieNode{children: make(map[rune]*TrieNode)}
        }
        node = node.children[c]
    }
    node.isEnd = true
}

func (t *Trie) Search(word string) bool {
    node := t.root
    for _, c := range word {
        if _, ok := node.children[c]; !ok {
            return false
        }
        node = node.children[c]
    }
    return node.isEnd
}

func (t *Trie) Delete(word string) {
    t.deleteHelper(t.root, word, 0)
}

func (t *Trie) deleteHelper(node *TrieNode, word string, index int) bool {
    if index == len(word) {
        if !node.isEnd {
            return false
        }
        node.isEnd = false
        return len(node.children) == 0
    }
    c := rune(word[index])
    if _, ok := node.children[c]; !ok {
        return false
    }
    child := node.children[c]
    shouldDelete := t.deleteHelper(child, word, index+1)
    if shouldDelete {
        delete(node.children, c)
        return len(node.children) == 0
    }
    return false
}

func main() {
    trie := NewTrie()
    trie.Insert("hello")
    trie.Insert("world")
    fmt.Println(trie.Search("hello")) // true
    fmt.Println(trie.Search("world")) // true
    fmt.Println(trie.Search("hi"))    // false
    trie.Delete("hello")
    fmt.Println(trie.Search("hello")) // false
}

 Go标准库中的字符串搜索函数(如strings.Contains、strings.Index等)在大多数情况下都是非常高效的,因为它们使用了一些优化算法来加速字符串搜索。

这些算法都是经过优化的,因此在大多数情况下都比较高效。但是在某些特殊情况下,如需要搜索的字符串非常长或者需要搜索的字符串数量非常多时,这些算法可能会变得比较慢。此时可以考虑使用Trie树等数据结构来加速字符串搜索。

 

posted @ 2023-04-29 10:54  GJH-  阅读(69)  评论(0编辑  收藏  举报