数据结构之字典树(前缀树)

一.字典树概念

字典树又被称作Trie树,其效率非常高,所以在字符串查找,前缀匹配中应用非常广泛,其高效率是以空间为代价的。典型应用是用于统计和排序大量的字符串,它的优点是,最大限度地减少无谓的字符串比较,查询效率比哈希表更高。

二.字典树特点

1,跟节点不存储数据

2,每个节点仅存储一个字符。

3,从根节点到每个节点上的路径,表示当前节点的表示的字符串(如果该节点是叶子结点),或者是字符串的前缀

4,每个节点的所有子节点包含的字符串不相同。

5,该结构使用了空间换时间的做法。

三,内存结构示例

 如上图 对应结构的特点。

四,代码示例

package main

import (
	"container/list"
	"fmt"
)

// 字典树
/*
特点:
1,跟节点不存储数据
2,每个节点仅存储一个字符
3,从根节点到每个节点上的路径,表示当前节点的表示的字符串(如果该节点是叶子结点),或者是字符串的前缀
4,每个节点的所有子节点包含的字符串不相同。

*/
type Node struct {
	IsEnd   bool // 是否叶子节点
	Context string // 当前节点存储的内容,并且如果是叶子结点,那么存储的就是整个字符串的内容
	Next    [26]*Node // 每一个字符的存储节点,会有许多的空节点,查询效率
}

func (n *Node) Insert(s string) {
	t := n
	for _, v := range s {
		if t.Next[v-'a'] == nil {
			// 构建新节点存储当前字符信息
			t.Next[v-'a'] = &Node{
				IsEnd:   false,
				Context: t.Context + string(v), // 当前节点的字符串信息
			}
		}
		t = t.Next[v-'a']
	}
	t.IsEnd = true
}

// 递归排过序的字符串
func (n *Node) DlSort() {
	if n == nil {
		return
	}
	if n.IsEnd {
		fmt.Println(n.Context)
		return
	}
	for i := 0; i < 26; i++ {
		n.Next[i].DlSort()
	}
}

// 按曾遍历
func (n *Node) Show() {
	if n == nil {
		return
	}
	queue := list.New()
	queue.PushBack(n)
	for queue.Len() != 0 {
		cnt := queue.Len()
		for i := 0; i < cnt; i++ {
			t := queue.Front() // 返回的value,需要断言成具体类型
			queue.Remove(t)
			if t.Value.(*Node).IsEnd {
				fmt.Println(t.Value.(*Node).Context)
			}
			for i := 0; i < 26; i++ {
				if t.Value.(*Node).Next[i] != nil {
					queue.PushBack(t.Value.(*Node).Next[i])
				}
			}
		}
	}
}

func (n *Node) Search(s string) bool {
	t := n
	for _, v := range s {
		t = t.Next[v-'a'] // 跳过跟节点,直接根据对应字符对应位置判断是否存在节点信息
		if t == nil {
			return false
		}
	}
	return t.IsEnd
}

// 前缀
func (n *Node) PrefixSearch(prefix string) bool {
	t := n
	for _, v := range prefix {
		t = t.Next[v-'a']
		if t == nil {
			return false
		}
	}
	return true
}

func main() {
	root := &Node{
		IsEnd: false,
	}

	strList := []string{"ls", "clear", "pwd", "cd"}
	for _, val := range strList {
		root.Insert(val)
	}

	fmt.Println(root.Search("ls"))
	fmt.Println(root.PrefixSearch("cle"))
	// root.DlSort()

	root.Show()
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值