mirror of
https://github.com/hlccd/goSTL.git
synced 2025-01-19 06:19:32 +08:00
新增了单词查找树Trie的实现
This commit is contained in:
parent
60b5a46905
commit
29dbcd9702
@ -13,9 +13,9 @@ package trie
|
|||||||
//以son为分叉存储下属的string
|
//以son为分叉存储下属的string
|
||||||
//该节点同时存储其元素
|
//该节点同时存储其元素
|
||||||
type node struct {
|
type node struct {
|
||||||
num int
|
num int //以当前结点为前缀的string的数量
|
||||||
son [64]*node
|
son [64]*node //分叉
|
||||||
value interface{}
|
value interface{} //当前结点承载的元素
|
||||||
}
|
}
|
||||||
|
|
||||||
//@title newNode
|
//@title newNode
|
||||||
@ -155,6 +155,36 @@ func (n *node) erase(s string, p int) (b bool) {
|
|||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//@title delete
|
||||||
|
//@description
|
||||||
|
// 以node单词查找树节点做接收者
|
||||||
|
// 从n节点中继续删除以s为索引的元素e,且当前抵达的string位置为p
|
||||||
|
// 当到达s终点时进行删除,删除所有后续元素,并返回其后续元素的数量
|
||||||
|
// 当未到达终点时,根据当前抵达的位置去寻找其子结点继续遍历即可,若其分叉为nil则直接返回0
|
||||||
|
//@receiver n *node 接受者node的指针
|
||||||
|
//@param s string 待删除元素的索引s
|
||||||
|
//@param p int 索引当前抵达的位置
|
||||||
|
//@return num int 被删除元素的数量
|
||||||
|
func (n *node) delete(s string, p int) (num int) {
|
||||||
|
if p == len(s) {
|
||||||
|
return n.num
|
||||||
|
}
|
||||||
|
idx := getIdx(s[p])
|
||||||
|
if idx == -1 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
if n.son[idx] == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
num = n.son[idx].delete(s, p+1)
|
||||||
|
if num>0 {
|
||||||
|
n.num-=num
|
||||||
|
if n.son[idx].num <= 0 {
|
||||||
|
n.son[idx] = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return num
|
||||||
|
}
|
||||||
//@title count
|
//@title count
|
||||||
//@description
|
//@description
|
||||||
// 以node单词查找树节点做接收者
|
// 以node单词查找树节点做接收者
|
||||||
|
@ -34,6 +34,7 @@ type trieer interface {
|
|||||||
Empty() (b bool) //判断该trie是否为空
|
Empty() (b bool) //判断该trie是否为空
|
||||||
Insert(s string, e interface{}) (b bool) //向trie中插入string并携带元素e
|
Insert(s string, e interface{}) (b bool) //向trie中插入string并携带元素e
|
||||||
Erase(s string) (b bool) //从trie中删除以s为索引的元素e
|
Erase(s string) (b bool) //从trie中删除以s为索引的元素e
|
||||||
|
Delete(s string) (num int) //从trie中删除以s为前缀的所有元素
|
||||||
Count(s string) (num int) //从trie中寻找以s为前缀的string单词数
|
Count(s string) (num int) //从trie中寻找以s为前缀的string单词数
|
||||||
Find(s string) (e interface{}) //从trie中寻找以s为索引的元素e
|
Find(s string) (e interface{}) //从trie中寻找以s为索引的元素e
|
||||||
}
|
}
|
||||||
@ -116,10 +117,7 @@ func (t *trie) Clear() {
|
|||||||
//@param nil
|
//@param nil
|
||||||
//@return b bool 该容器是空的吗?
|
//@return b bool 该容器是空的吗?
|
||||||
func (t *trie) Empty() (b bool) {
|
func (t *trie) Empty() (b bool) {
|
||||||
if t.Size() > 0 {
|
return t.size == 0
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//@title Insert
|
//@title Insert
|
||||||
@ -191,6 +189,43 @@ func (t *trie) Erase(s string) (b bool) {
|
|||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//@title Delete
|
||||||
|
//@description
|
||||||
|
// 以trie单词查找树做接收者
|
||||||
|
// 从trie树中删除以s为前缀的所有元素
|
||||||
|
//@receiver t *trie 接受者trie的指针
|
||||||
|
//@param s string 待删除元素的前缀
|
||||||
|
//@return num int 被删除的元素的数量
|
||||||
|
func (t *trie) Delete(s string) (num int) {
|
||||||
|
if t == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
if t.Empty() {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
if len(s) == 0 {
|
||||||
|
//长度为0无法删除
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
if t.root == nil {
|
||||||
|
//根节点为nil即无法删除
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
t.mutex.Lock()
|
||||||
|
//从根节点开始删除
|
||||||
|
num = t.root.delete(s, 0)
|
||||||
|
if num > 0 {
|
||||||
|
//删除成功
|
||||||
|
t.size -= num
|
||||||
|
if t.size <= 0 {
|
||||||
|
//所有string都被删除,根节点置为nil
|
||||||
|
t.root = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
t.mutex.Unlock()
|
||||||
|
return num
|
||||||
|
}
|
||||||
|
|
||||||
//@title Count
|
//@title Count
|
||||||
//@description
|
//@description
|
||||||
// 以trie单词查找树做接收者
|
// 以trie单词查找树做接收者
|
||||||
|
Loading…
x
Reference in New Issue
Block a user