forked from peco/peco
/
trie.go
101 lines (91 loc) · 1.38 KB
/
trie.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package keyseq
import (
"container/list"
)
type Trie interface {
Root() Node
GetList(KeyList) Node
Get(Key) Node
Put(KeyList, interface{}) Node
Size() int
}
func NewTrie() Trie {
return NewTernaryTrie()
}
func Get(t Trie, k KeyList) Node {
if t == nil {
return nil
}
n := t.Root()
for _, c := range k {
n = n.Get(c)
if n == nil {
return nil
}
}
return n
}
func Put(t Trie, k KeyList, v interface{}) Node {
if t == nil {
return nil
}
n := t.Root()
for _, c := range k {
n, _ = n.Dig(c)
}
n.SetValue(v)
return n
}
func EachDepth(t Trie, proc func(Node) bool) {
if t == nil {
return
}
r := t.Root()
var f func(Node) bool
f = func(n Node) bool {
n.Each(f)
return proc(n)
}
r.Each(f)
}
func EachWidth(t Trie, proc func(Node) bool) {
if t == nil {
return
}
q := list.New()
q.PushBack(t.Root())
for q.Len() != 0 {
f := q.Front()
q.Remove(f)
t := f.Value.(Node)
if !proc(t) {
break
}
t.Each(func(n Node) bool {
q.PushBack(n)
return true
})
}
}
type Node interface {
Get(k Key) Node
GetList(k KeyList) Node
Dig(k Key) (Node, bool)
HasChildren() bool
Size() int
Each(func(Node) bool)
RemoveAll()
Label() Key
Value() interface{}
SetValue(v interface{})
}
func Children(n Node) []Node {
children := make([]Node, n.Size())
idx := 0
n.Each(func(n Node) bool {
children[idx] = n
idx++
return true
})
return children
}