diff --git a/goSTL/data_structure/trie/node.go b/goSTL/data_structure/trie/node.go index 68474b2..1347567 100644 --- a/goSTL/data_structure/trie/node.go +++ b/goSTL/data_structure/trie/node.go @@ -13,9 +13,9 @@ package trie //以son为分叉存储下属的string //该节点同时存储其元素 type node struct { - num int - son [64]*node - value interface{} + num int //以当前结点为前缀的string的数量 + son [64]*node //分叉 + value interface{} //当前结点承载的元素 } //@title newNode @@ -155,6 +155,36 @@ func (n *node) erase(s string, p int) (b bool) { 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 //@description // 以node单词查找树节点做接收者 diff --git a/goSTL/data_structure/trie/trie.go b/goSTL/data_structure/trie/trie.go index dceec73..4ac9e3e 100644 --- a/goSTL/data_structure/trie/trie.go +++ b/goSTL/data_structure/trie/trie.go @@ -34,6 +34,7 @@ type trieer interface { Empty() (b bool) //判断该trie是否为空 Insert(s string, e interface{}) (b bool) //向trie中插入string并携带元素e Erase(s string) (b bool) //从trie中删除以s为索引的元素e + Delete(s string) (num int) //从trie中删除以s为前缀的所有元素 Count(s string) (num int) //从trie中寻找以s为前缀的string单词数 Find(s string) (e interface{}) //从trie中寻找以s为索引的元素e } @@ -116,10 +117,7 @@ func (t *trie) Clear() { //@param nil //@return b bool 该容器是空的吗? func (t *trie) Empty() (b bool) { - if t.Size() > 0 { - return false - } - return true + return t.size == 0 } //@title Insert @@ -191,6 +189,43 @@ func (t *trie) Erase(s string) (b bool) { 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 //@description // 以trie单词查找树做接收者