Trie树的Go实现

Trie树是一种多叉树数据结构,常用于存储具有公共前缀的字符串集合,拥有节省空间、快速查找的特性。

受到https://oreki.blog.csdn.net/article/details/109076473的C++实现Trie的启发,尝试使用Go来实现Trie树:

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

type TrieTree struct {
	root *TrieNode
}

func NewTrieTree() *TrieTree {
	return &TrieTree{
		root: &TrieNode{
			data:    0,
			isEnd:   false,
			subNode: make(map[rune]*TrieNode),
		},
	}
}

//插入字符串
func (t *TrieTree) Insert(s string) {
	if s == "" {
		return
	}
	cur := t.root
	for _, char := range s {
		if _, ok := cur.subNode[char]; !ok {
			cur.subNode[char] = &TrieNode{
				data:    char,
				isEnd:   false,
				subNode: make(map[rune]*TrieNode),
			}
		}
		cur = cur.subNode[char]
	}
	cur.isEnd = true
}

func (t *TrieTree) Find(s string) bool {
	if s == "" {
		return false
	}
	cur := t.root
	for _, char := range s {
		if _, ok := cur.subNode[char]; !ok {
			return false
		}
		cur = cur.subNode[char]
	}
	//如果要在含hello的Trie树中中找he,当遍历完he的每个字符,都与hello的前缀一致,但是trie树的e的node属性isEnd是false,表明Trie树不含he字符
	return cur.isEnd
}

func (t *TrieTree) StartsWith(prefix string) bool {
	if prefix == "" {
		return false
	}
	cur := t.root
	for _, char := range prefix {
		if _, ok := cur.subNode[char]; !ok {
			return false
		}
		cur = cur.subNode[char]
	}
	return true
}

func (t *TrieTree) GetPrefixWords(prefix string) []string {
	if prefix == "" {
		return nil
	}
	cur := t.root
	for _, char := range prefix {
		if _, ok := cur.subNode[char]; !ok {
			return nil
		}
		cur = cur.subNode[char]
	}

	var result []string
	t.getPrefixWordsHelper(cur, prefix, &result)
	return result
}

func (t *TrieTree) getPrefixWordsHelper(cur *TrieNode, str string, result *[]string) {
	if cur.isEnd {
		*result = append(*result, str)
	}
	for char, subNode := range cur.subNode {
		t.getPrefixWordsHelper(subNode, str+string(char), result)
	}
}

func main() {
	trie := NewTrieTree()

	words := []string{"bat", "batman", "batter", "bath", "apple", "apricot", "banana"}
	for _, word := range words {
		trie.Insert(word)
	}

	fmt.Println(trie.Find("bat"))      // true
	fmt.Println(trie.Find("batter"))   // true
	fmt.Println(trie.Find("batwoman")) // false

	fmt.Println(trie.StartsWith("ba"))  // true
	fmt.Println(trie.StartsWith("bat")) // true
	fmt.Println(trie.StartsWith("foo")) // false

	fmt.Println(trie.GetPrefixWords("ba")) // [banana, bat, batman, batter, bath]
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值