-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathtreap.go
341 lines (299 loc) · 8.33 KB
/
treap.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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
// Copyright 2011 Numerotron Inc.
// Use of this source code is governed by an MIT-style license
// that can be found in the LICENSE file.
//
// Developed at www.stathat.com by Patrick Crosby
// Contact us on twitter with any questions: twitter.com/stat_hat
// The treap package provides a balanced binary tree datastructure, expected
// to have logarithmic height.
package treap
import (
"rand"
"time"
)
func init() {
rand.Seed(time.Nanoseconds())
}
// A Tree is the data structure that stores everything
type Tree struct {
less LessFunc
overlap OverlapFunc
count int
root *Node
}
// LessFunc returns true if a < b
type LessFunc func(a, b interface{}) bool
// OverlapFunc return true if a overlaps b. Optional. Only used by overlap trees.
type OverlapFunc func(a, b interface{}) bool
// Key can be anything. It will use LessFunc to compare keys.
type Key interface{}
// Item can be anything.
type Item interface{}
// A Node in the Tree.
type Node struct {
key Key
item Item
priority int
left *Node
right *Node
}
func newNode(key Key, item Item, priority int) *Node {
result := new(Node)
result.key = key
result.item = item
result.priority = priority
return result
}
// To create a Tree, you need to supply a LessFunc that can compare the
// keys in the Node.
func NewTree(lessfn LessFunc) *Tree {
t := new(Tree)
t.less = lessfn
return t
}
// To create a tree that also lets you iterate by key overlap, supply a LessFunc
// and an OverlapFunc
func NewOverlapTree(lessfn LessFunc, overfn OverlapFunc) *Tree {
t := new(Tree)
t.less = lessfn
t.overlap = overfn
return t
}
// Remove everything from the tree.
func (t *Tree) Reset() {
t.root = nil
t.count = 0
}
// The length of the tree (number of nodes).
func (t *Tree) Len() int {
return t.count
}
// Get an Item in the tree.
func (t *Tree) Get(key Key) Item {
return t.get(t.root, key)
}
func (t *Tree) get(node *Node, key Key) Item {
if node == nil {
return nil
}
if t.less(key, node.key) {
return t.get(node.left, key)
}
if t.less(node.key, key) {
return t.get(node.right, key)
}
return node.item
}
// Returns true if there is an item in the tree with this key.
func (t *Tree) Exists(key Key) bool {
return t.exists(t.root, key)
}
func (t *Tree) exists(node *Node, key Key) bool {
if node == nil {
return false
}
if t.less(key, node.key) {
return t.exists(node.left, key)
}
if t.less(node.key, key) {
return t.exists(node.right, key)
}
return true
}
// Insert an item into the tree.
func (t *Tree) Insert(key Key, item Item) {
priority := rand.Int()
t.root = t.insert(t.root, key, item, priority)
}
func (t *Tree) insert(node *Node, key Key, item Item, priority int) *Node {
if node == nil {
t.count++
return newNode(key, item, priority)
}
if t.less(key, node.key) {
node.left = t.insert(node.left, key, item, priority)
if node.left.priority < node.priority {
return t.leftRotate(node)
}
return node
}
if t.less(node.key, key) {
node.right = t.insert(node.right, key, item, priority)
if node.right.priority < node.priority {
return t.rightRotate(node)
}
return node
}
// equal: replace the value
node.item = item
return node
}
func (t *Tree) leftRotate(node *Node) *Node {
result := node.left
x := result.right
result.right = node
node.left = x
return result
}
func (t *Tree) rightRotate(node *Node) *Node {
result := node.right
x := result.left
result.left = node
node.right = x
return result
}
// Split the tree by creating a tree with a node of priority -1 so it will be the root
func (t *Tree) Split(key Key) (*Node, *Node) {
inserted := t.insert(t.root, key, nil, -1)
return inserted.left, inserted.right
}
// Merge two trees together by supplying the root node of each tree.
func (t *Tree) Merge(left, right *Node) *Node {
if left == nil {
return right
}
if right == nil {
return left
}
if left.priority < right.priority {
result := left
x := left.right
result.right = t.Merge(x, right)
return result
}
result := right
x := right.left
result.left = t.Merge(x, left)
return result
}
// Delete the item from the tree that has this key.
func (t *Tree) Delete(key Key) {
if t.Exists(key) == false {
return
}
t.root = t.delete(t.root, key)
}
func (t *Tree) delete(node *Node, key Key) *Node {
if node == nil {
panic("key not found")
}
if t.less(key, node.key) {
result := node
x := node.left
result.left = t.delete(x, key)
return result
}
if t.less(node.key, key) {
result := node
x := node.right
result.right = t.delete(x, key)
return result
}
t.count--
return t.Merge(node.left, node.right)
}
// Returns the height (depth) of the tree.
func (t *Tree) Height(key Key) int {
return t.height(t.root, key)
}
func (t *Tree) height(node *Node, key Key) int {
if node == nil {
return 0
}
if t.less(key, node.key) {
depth := t.height(node.left, key)
return depth + 1
}
if t.less(node.key, key) {
depth := t.height(node.right, key)
return depth + 1
}
return 0
}
// Returns a channel of Items whose keys are in ascending order.
func (t *Tree) IterAscend() <-chan Item {
c := make(chan Item)
go func() {
iterateInOrder(t.root, c)
close(c)
}()
return c
}
func iterateInOrder(h *Node, c chan<- Item) {
if h == nil {
return
}
iterateInOrder(h.left, c)
c <- h.item
iterateInOrder(h.right, c)
}
// Returns a channel of keys in ascending order.
func (t *Tree) IterKeysAscend() <-chan Key {
c := make(chan Key)
go func() {
iterateKeysInOrder(t.root, c)
close(c)
}()
return c
}
func iterateKeysInOrder(h *Node, c chan<- Key) {
if h == nil {
return
}
iterateKeysInOrder(h.left, c)
c <- h.key
iterateKeysInOrder(h.right, c)
}
// Returns a channel of items that overlap key.
func (t *Tree) IterateOverlap(key Key) <-chan Item {
c := make(chan Item)
go func() {
if t.overlap != nil {
t.iterateOverlap(t.root, key, c)
}
close(c)
}()
return c
}
func (t *Tree) iterateOverlap(h *Node, key Key, c chan<- Item) {
if h == nil {
return
}
lessThanLower := t.overlap(h.key, key)
greaterThanUpper := t.overlap(key, h.key)
if !lessThanLower {
t.iterateOverlap(h.left, key, c)
}
if !lessThanLower && !greaterThanUpper {
c <- h.item
}
if !greaterThanUpper {
t.iterateOverlap(h.right, key, c)
}
}
// Returns the minimum item in the tree.
func (t *Tree) Min() Item {
return min(t.root)
}
func min(h *Node) Item {
if h == nil {
return nil
}
if h.left == nil {
return h.item
}
return min(h.left)
}
// Returns the maximum item in the tree.
func (t *Tree) Max() Item {
return max(t.root)
}
func max(h *Node) Item {
if h == nil {
return nil
}
if h.right == nil {
return h.item
}
return max(h.right)
}