tree-red_black 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 01243ab97c7f5ed1ac6ff3dcb41b9e9c62bbfa709c348df9ba0c69c69b652974
4
+ data.tar.gz: 6109eec9ae6ec7d0de5f583d50588c7aa349efad76ab9b987ea857afc442ad2e
5
+ SHA512:
6
+ metadata.gz: df4e50125126871fb649f3316082fc38dd9fe472003411f5d50dca93d4ccd64fbb7dc537ba7a1df95448ad6342c157b95325946f29a88b918b7b5dfe4bea41d0
7
+ data.tar.gz: e8b85911d1606729def0deba609fca3316bd986c11dc837a75409d255176588c63fc4845b1db75aa1f0812509956dd11775c4fca09a454cd7722b82acfe9b616
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /html/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+
11
+ # rspec failure tracking
12
+ .rspec_status
@@ -0,0 +1,10 @@
1
+ dist: xenial
2
+ language: ruby
3
+ rvm:
4
+ - 2.5.0
5
+ sudo: true
6
+ before_install:
7
+ - gem update --system
8
+ - gem install bundler -v 2.0.1
9
+ script:
10
+ - bundle exec rspec spec && gem build tree-red_black.gemspec && gem install tree-red_black*gem
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at TODO: Write your email address. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in tree-red_black.gemspec
4
+ gemspec
@@ -0,0 +1,36 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ tree-red_black (0.4.2)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.3)
10
+ rake (13.0.1)
11
+ rspec (3.9.0)
12
+ rspec-core (~> 3.9.0)
13
+ rspec-expectations (~> 3.9.0)
14
+ rspec-mocks (~> 3.9.0)
15
+ rspec-core (3.9.2)
16
+ rspec-support (~> 3.9.3)
17
+ rspec-expectations (3.9.2)
18
+ diff-lcs (>= 1.2.0, < 2.0)
19
+ rspec-support (~> 3.9.0)
20
+ rspec-mocks (3.9.1)
21
+ diff-lcs (>= 1.2.0, < 2.0)
22
+ rspec-support (~> 3.9.0)
23
+ rspec-support (3.9.3)
24
+
25
+ PLATFORMS
26
+ ruby
27
+
28
+ DEPENDENCIES
29
+ bundler (~> 2.0, >= 2.0.1)
30
+ rake (~> 13.0)
31
+ rspec (~> 3.8)
32
+ rspec-expectations (~> 3.8)
33
+ tree-red_black!
34
+
35
+ BUNDLED WITH
36
+ 2.1.4
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 TODO: Write your name
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,572 @@
1
+ [![Build Status](https://travis-ci.com/slewsys/tree-red_black.svg?branch=master)](https://travis-ci.com/slewsys/tree-red_black)
2
+
3
+ # Tree::RedBlack
4
+
5
+ - [Description](#description)
6
+ - [Installation](#installation)
7
+ - [Tree::RedBlack API](#treeredblack-api)
8
+ - [new(allow_duplicates = true) &#8594; red_black_tree](#newallow_duplicates--true--red_black_tree)
9
+ - [insert(value, ...) &#8594; red_black_tree](#insertvalue---red_black_tree)
10
+ - [delete(value, ...) &#8594; red_black_tree](#deletevalue---red_black_tree)
11
+ - [search(value, ifnone = nil) &#8594; red_black_node](#searchvalue-ifnone--nil--red_black_node)
12
+ - [bsearch { |node| block } &#8594; red_black_node](#bsearch--node-block---red_black_node)
13
+ - [pre_order &#8594; node_enumerator](#pre_order--node_enumerator)
14
+ - [in_order &#8594; node_enumerator](#in_order--node_enumerator)
15
+ - [dup &#8594; red_black_tree](#dup--red_black_tree)
16
+ - [Tree::RedBlackNode API](#treeredblacknode-api)
17
+ - [new(value = nil, color = :RED) &#8594; red_black_node](#newvalue--nil-color--red--red_black_node)
18
+ - [insert_red_black(value, allow_duplicates = true) &#8594; red_black_node](#insert_red_blackvalue-allow_duplicates--true--red_black_node)
19
+ - [delete_red_black(value) &#8594; red_black_node](#delete_red_blackvalue--red_black_node)
20
+ - [search(value, ifnone = nil) &#8594; red_black_node](#searchvalue-ifnone--nil--red_black_node-1)
21
+ - [bsearch(&block) &#8594; red_black_node](#bsearchblock--red_black_node)
22
+ - [min() &#8594; red_black_node](#min--red_black_node)
23
+ - [max() &#8594; red_black_node](#max--red_black_node)
24
+ - [pred() &#8594; red_black_node](#pred--red_black_node)
25
+ - [succ() &#8594; red_black_node](#succ--red_black_node)
26
+ - [pre_order(&block) &#8594; red_black_node](#pre_orderblock--red_black_node)
27
+ - [in_order(&block) &#8594; red_black_node](#in_orderblock--red_black_node)
28
+ - [dup() &#8594; red_black_node](#dup--red_black_node)
29
+ - [Contributing](#contributing)
30
+ - [License](#license)
31
+
32
+ ## Description
33
+
34
+ The __Tree::RedBlack__ library is a pure-Ruby implementation of
35
+ a [Red-Black tree](https://en.wikipedia.org/wiki/Red–black_tree) --
36
+ i.e., a self-balancing binary tree
37
+ with [O(log n)](https://en.wikipedia.org/wiki/Big-O_notation) search,
38
+ insert and delete operations. It is appropriate for maintaining a
39
+ sorted collection where insertion and deletion are desired at
40
+ arbitrary positions.
41
+
42
+ This implementation differs slightly from the Wikipedia description
43
+ referenced above. In particular, leaf nodes are `nil`, which affects the
44
+ details of node deletion.
45
+
46
+ ## Installation
47
+ With a recent version of the [Ruby](https://www.ruby-lang.org/en/)
48
+ interpreter installed (e.g., ruby 2.5), run the following commands
49
+ from a Unix shell:
50
+
51
+ ```bash
52
+ git clone git@github.com:slewsys/tree-red_black.git
53
+ cd tree-red_black
54
+ sudo gem update --system
55
+ bundle
56
+ rake build
57
+ sudo gem install pkg/tree-red_black*.gem
58
+ ```
59
+
60
+ The RSpec test suite can be run with:
61
+
62
+ ```bash
63
+ bundle exec rspec spec
64
+ ```
65
+
66
+ To build RDoc documentation, use:
67
+
68
+ ```bash
69
+ rake rdoc
70
+ ```
71
+
72
+ ## Tree::RedBlack API
73
+
74
+ Once a Red-Black tree has been instantiated
75
+ (see
76
+ [new](#newallow_duplicates--true--red_black_tree)),
77
+ any [Comparable](https://docs.ruby-lang.org/en/2.7.0/Comparable.html)
78
+ value can be stored, provided that every value in the tree is
79
+ comparable with every other. Values are stored in nodes and referenced
80
+ by the `key` attribute of the node. Nodes are added to a Red-Black
81
+ tree by inserting values
82
+ (see
83
+ [insert](#insertvalue---red_black_tree)),
84
+ and nodes are removed by deleting values
85
+ (see
86
+ [delete](#deletevalue---red_black_tree)).
87
+
88
+ A Red-Black tree's nodes can be enumerated in ascending order by value
89
+ with the tree's [each](#in_order--node_enumerator) method. Additional
90
+ enumeration methods are described
91
+ in [Enumerable](https://ruby-doc.org/core-2.7.0/Enumerable.html).
92
+
93
+ ### new(allow_duplicates = true) &#8594; red_black_tree
94
+
95
+ Returns a new, empty Red-Black tree. If option `allow_duplicates` is
96
+ `false`, then only unique values are inserted in a Red-Black tree.
97
+
98
+ The `root` attribute references the root node of the tree.
99
+ The `size` attribute indicates the number of nodes in the tree.
100
+ When `size` is `0`, `root` is always `nil`.
101
+
102
+ Example:
103
+
104
+ ```ruby
105
+ require 'tree/red_black'
106
+
107
+ rbt = Tree::RedBlack.new
108
+ p rbt.root #=> nil
109
+ p rbt.size #=> 0
110
+ p rbt.allow_duplicates? #=> true
111
+ ```
112
+
113
+ ### insert(value, ...) &#8594; red_black_tree
114
+
115
+ Inserts a value or sequence of values in a Red-Black tree and
116
+ increments the `size` attribute by the number of values inserted.
117
+
118
+ Since a Red-Black tree maintains a sorted, [Enumerable](https://ruby-doc.org/core-2.7.0/Enumerable.html) collection,
119
+ every value inserted must be comparable with every other value.
120
+ Methods `each`, `map`, `select`, `find`, `sort`, etc., can be applied
121
+ directly to the tree.
122
+
123
+ The individual nodes yielded by enumeration respond to method `key` to
124
+ retrieve the value stored in that node. Method `each`, in particular,
125
+ is aliased to `in_order`, so that nodes are sorted in ascending order
126
+ by `key` value. Nodes can also be traversed by method `pre_order`,
127
+ e.g., to generate paths in the tree.
128
+
129
+ Example:
130
+
131
+ ```ruby
132
+ require 'tree/red_black'
133
+
134
+ rbt = Tree::RedBlack.new
135
+ rbt.insert(*1..10) # #<Tree::RedBlack:0x00...>
136
+ p rbt.size #=> 10
137
+ rbt.map(&:key) #=> [1, 2, ..., 10]
138
+ rbt.select { |node| node.key % 2 == 0 }.map(&:key)
139
+ #=> [2, 4, ..., 10]
140
+ ```
141
+
142
+ ### delete(value, ...) &#8594; red_black_tree
143
+
144
+ Deletes a value or sequence of values from a Red-Black tree.
145
+
146
+ Example:
147
+
148
+ ```ruby
149
+ require 'tree/red_black'
150
+
151
+ rbt = Tree::RedBlack.new
152
+ rbt.insert(*1..10) # #<Tree::RedBlack:0x00...>
153
+ p rbt.size #=> 10
154
+ rbt.delete(*4..8) # #<Tree::RedBlack:0x00...>
155
+ p rbt.size #=> 5
156
+ rbt.map(&:key) #=> [1, 2, 3, 9, 10]
157
+ ```
158
+
159
+ ### search(value, ifnone = nil) &#8594; red_black_node
160
+
161
+ Returns a Red-Black tree node whose `key` matches `value` by binary
162
+ search. If no match is found, calls non-nil `ifnone`, otherwise
163
+ returns `nil`.
164
+
165
+ Example:
166
+
167
+ ```ruby
168
+ require 'tree/red_black'
169
+
170
+ shuffled_values = [*1..10].shuffle
171
+ rbt = shuffled_values.reduce(Tree::RedBlack.new) do |acc, v|
172
+ acc.insert(v)
173
+ end
174
+ rbt.search(7) #=> <Tree::RedBlackNode:0x00..., @key=7, ...>
175
+ ```
176
+
177
+ ### bsearch { |node| block } &#8594; red_black_node
178
+
179
+ Returns a Red-Black tree node satisfying a criterion defined in
180
+ `block` by binary search.
181
+
182
+ If `block` evaluates to `true` or `false`, returns the first node for
183
+ which the `block` evaluates to `true`. In this case, the criterion is
184
+ expected to return `false` for nodes preceding the matching node and
185
+ `true` for subsequent nodes.
186
+
187
+ Example:
188
+
189
+ ```ruby
190
+ require 'tree/red_black'
191
+
192
+ shuffled_values = [*1..10].shuffle
193
+ rbt = shuffled_values.reduce(Tree::RedBlack.new) do |acc, v|
194
+ acc.insert(v)
195
+ end
196
+ rbt.bsearch { |node| node.key >= 7 }
197
+ #=> <Tree::RedBlackNode:0x00..., @key=7, ...>
198
+ ```
199
+
200
+ If `block` evaluates to `<0`, `0` or `>0`, returns first node for
201
+ which `block` evaluates to `0`. Otherwise returns `nil`. In this case,
202
+ the criterion is expected to return `<0` for nodes preceding the
203
+ matching node, `0` for some subsequent nodes and `>0` for nodes beyond
204
+ that.
205
+
206
+ Example:
207
+
208
+ ```ruby
209
+ require 'tree/red_black'
210
+
211
+ shuffled_values = [*1..10].shuffle
212
+ rbt = shuffled_values.reduce(Tree::RedBlack.new) do |acc, v|
213
+ acc.insert(v)
214
+ end
215
+ rbt.bsearch { |node| 7 <=> node.key }
216
+ #=> <Tree::RedBlackNode:0x00..., @key=7, ...>
217
+ ```
218
+
219
+ If `block` is not given, returns an enumerator.
220
+
221
+ ### pre_order &#8594; node_enumerator
222
+
223
+ Returns an enumerator for nodes in a Red-Black tree by pre-order
224
+ traversal.
225
+
226
+ Example:
227
+
228
+ ```ruby
229
+ require 'tree/red_black'
230
+
231
+ rbt = Tree::RedBlack.new
232
+ shuffled_values = [*1..10].shuffle #=> [5, 9, 10, 8, 7, 6, 1, 2, 4, 3]
233
+ rbt.insert(*shuffled_values) #=> #<Tree::RedBlack:0x00...>
234
+ rbt.pre_order.map(&:key) #=> [7, 5, 2, 1, 4, 3, 6, 9, 8, 10]
235
+ ```
236
+
237
+ ### in_order &#8594; node_enumerator
238
+
239
+ Returns an enumerator for nodes in a Red-Black tree by in-order
240
+ traversal. The `each` method is aliased to `in_order`.
241
+
242
+ Example:
243
+
244
+ ```ruby
245
+ require 'tree/red_black'
246
+
247
+ rbt = Tree::RedBlack.new
248
+ shuffled_values = [*1..10].shuffle
249
+ rbt.insert(*shuffled_values)
250
+ rbt.in_order.map(&:key) #=> [1, 2, ... 9, 10]
251
+ ```
252
+
253
+ ### dup &#8594; red_black_tree
254
+
255
+ Returns a deep copy of a Red-Black tree, provided that the `dup`
256
+ method for the `key` attribute of a tree node is also a deep copy.
257
+
258
+ Example:
259
+
260
+ ```ruby
261
+ require 'tree/red_black'
262
+
263
+ rbt = Tree::RedBlack.new
264
+ rbt.insert({a: 1, b: 2})
265
+ rbt_copy = rbt.dup
266
+ p rbt.root.key #=> {:a=>1, :b=>2}
267
+ p rbt.root.key.delete(:a) #=> 1
268
+ p rbt.root.key #=> {:b=>2}
269
+ p rbt_copy.root.key #=> {:a=>1, :b=>2}
270
+ ```
271
+
272
+ ### Tree::RedBlackNode API
273
+
274
+ A Red-Black tree is a collection of nodes arranged as a binary tree.
275
+ In addition to the binary node attributes `left` and `right`, which
276
+ reference the left and right sub-trees of a given node, and the
277
+ attribute `key` which stores a node's data, a Red-Black tree node
278
+ also has attributes `color` and `parent`.
279
+
280
+ The `color` attribute is used internally to balance the tree after a
281
+ node is inserted or deleted. The `parent` attribute references a
282
+ node's parent node, or `nil` in the case of the root node of a tree.
283
+
284
+ Not all implementations of Red-Black trees have nodes with `parent`
285
+ attributes, but it's generally recognized as the most efficient way
286
+ of balancing and re-coloring a Red-Black tree.
287
+
288
+ Since the data in a binary tree can be thought of as a sorted
289
+ collection, it's convenient to be able to refer to a node's
290
+ predecessor and successor (i.e., the node whose `key` is the
291
+ predecessor or successor in the sorted ascending order. In general,
292
+ this differs from parent or child node). This is provided as the node
293
+ methods `pred` and `succ`. And for a given sub-tree, its convenient to
294
+ be able to refer to its min and max nodes (i.e., the node whose `key`
295
+ is a minimum or maximum in the sub-tree). This is provided as the node
296
+ methods `min` and `max`.
297
+
298
+ While a Red-Black tree can be constructed from nodes alone, the
299
+ [Tree::RedBlack API](#treeredblack-api)
300
+ provides a cleaner way of working with Red-Black trees. Start
301
+ there if only using the Red-Black tree as a container.
302
+
303
+ ### new(value = nil, color = :RED) &#8594; red_black_node
304
+
305
+ Returns a new node with `key` parameter set to option `value`. The
306
+ `color` option, if given, must be be either `:RED` or `:BLACK`.
307
+
308
+ Example:
309
+
310
+ ```ruby
311
+ require 'tree/red_black'
312
+
313
+ root = Tree::RedBlackNode.new(10)
314
+ p root.key #=> 10
315
+ p root.color #=> :RED
316
+ p root.parent #=> nil
317
+ p root.left #=> nil
318
+ p root.right #=> nil
319
+ ```
320
+
321
+ ### insert_red_black(value, allow_duplicates = true) &#8594; red_black_node
322
+
323
+ Inserts the given `value` in a tree whose root node is `self`. If the
324
+ `key` attribute of the root node is `nil`, then `value` is assigned to
325
+ `key`. Otherwise, `value` is used to instantiate Tree::RedBlackNode,
326
+ and the node is inserted in the tree; the tree is then re-balanced as
327
+ needed, and the root of the balanced tree returned.
328
+
329
+ Since a Red-Black tree maintains an ordered, Enumerable collection,
330
+ every value inserted must be Comparable with every other value.
331
+ Methods `each`, `map`, `select`, `find`, `sort`, etc., can be applied
332
+ to a Red-Black tree's root node to iterate over all nodes in the tree.
333
+
334
+ Each node yielded by enumeration has a `key` attribute to
335
+ retrieve the value stored in that node. Method `each`, in particular,
336
+ is aliased to `in_order`, so that nodes are sorted in ascending order
337
+ by `key` value. Nodes can also be traversed by method `pre_order`,
338
+ e.g., to generate paths in the tree.
339
+
340
+ Example:
341
+
342
+ ```ruby
343
+ require 'tree/red_black'
344
+
345
+ root = Tree::RedBlackNode.new
346
+ p root.key #=> nil
347
+ root = root.insert_red_black(0)
348
+ p root.key #=> 0
349
+ root = root.insert_red_black(1)
350
+ p root.key #=> 0
351
+ p root.left #=> nil
352
+ p root.right.key #=> 1
353
+ root = root.insert_red_black(2)
354
+ p root.key #=> 1
355
+ p root.left.key #=> 0
356
+ p root.right.key #=> 2
357
+ ```
358
+
359
+ ### delete_red_black(value) &#8594; red_black_node
360
+
361
+ Deletes the given `value` from a tree whose root node is `self`.
362
+ If the tree has only one remaining node and its `key` attribute
363
+ matches `value`, then the remaining node's `key` attribute is set to
364
+ `nil` but the node itself is not removed. Otherwise, the first node
365
+ found whose `key` matches `value` is removed from the tree, and the
366
+ tree is re-balanced. The root of the balanced tree is returned.
367
+
368
+ Example:
369
+
370
+ ```ruby
371
+ require 'tree/red_black'
372
+
373
+ root = [*1..10].reduce(Tree::RedBlackNode.new) do |acc, v|
374
+ acc.insert_red_black(v)
375
+ end
376
+ root = [*4..8].reduce(root) do |acc, v|
377
+ acc.delete_red_black(v)
378
+ end
379
+ root.map(&:key) #=> [1, 2, 3, 9, 10]
380
+ ```
381
+
382
+ ### search(value, ifnone = nil) &#8594; red_black_node
383
+
384
+ Returns a node whose `key` matches `value` by binary search. If no
385
+ match is found, calls non-nil `ifnone`, otherwise returns `nil`.
386
+
387
+ Example:
388
+
389
+ ```ruby
390
+ require 'tree/red_black'
391
+
392
+ shuffled_values = [*1..10].shuffle
393
+ root = shuffled_values.reduce(Tree::RedBlackNode.new) do |acc, v|
394
+ acc.insert_red_black(v)
395
+ end
396
+ root.search(7) #=> <Tree::RedBlackNode:0x00..., @key=7, ...>
397
+ ```
398
+
399
+ ### bsearch(&block) &#8594; red_black_node
400
+
401
+ Returns a node satisfying a criterion defined in `block` by binary
402
+ search.
403
+
404
+ If `block` evaluates to `true` or `false`, returns the first node for
405
+ which the `block` evaluates to `true`. In this case, the criterion is
406
+ expected to return `false` for nodes preceding the matching node and
407
+ `true` for subsequent nodes.
408
+
409
+ Example:
410
+
411
+ ```ruby
412
+ require 'tree/red_black'
413
+
414
+ shuffled_values = [*1..10].shuffle
415
+ rbt = shuffled_values.reduce(Tree::RedBlack.new) do |acc, v|
416
+ acc.insert(v)
417
+ end
418
+ rbt.bsearch { |node| node.key >= 7 }
419
+ #=> <Tree::RedBlackNode:0x00..., @key=7, ...>
420
+ ```
421
+
422
+ If `block` evaluates to `<0`, `0` or `>0`, returns first node for
423
+ which `block` evaluates to `0`. Otherwise returns `nil`. In this case,
424
+ the criterion is expected to return `<0` for nodes preceding the
425
+ matching node, `0` for some subsequent nodes and `>0` for nodes beyond
426
+ that.
427
+
428
+ Example:
429
+
430
+ ```ruby
431
+ require 'tree/red_black'
432
+
433
+ shuffled_values = [*1..10].shuffle
434
+ rbt = shuffled_values.reduce(Tree::RedBlack.new) do |acc, v|
435
+ acc.insert(v)
436
+ end
437
+ rbt.bsearch { |node| 7 <=> node.key }
438
+ #=> <Tree::RedBlackNode:0x00..., @key=7, ...>
439
+ ```
440
+
441
+ If `block` is not given, returns an enumerator.
442
+
443
+ ### min() &#8594; red_black_node
444
+
445
+ Returns the node whose `key` is a minimum in the sub-tree with root `self`.
446
+
447
+ Example:
448
+
449
+ ```ruby
450
+ require 'tree/red_black'
451
+
452
+ root = [*0..10].reduce(Tree::RedBlackNode.new) do |acc, v|
453
+ acc.insert_red_black(v)
454
+ end
455
+ root #=> <Tree::RedBlackNode:0x00..., @key=4, ...>
456
+ root.min #=> <Tree::RedBlackNode:0x00..., @key=0, ...>
457
+ root.right #=> <Tree::RedBlackNode:0x00..., @key=6, ...>
458
+ root.right.min #=> <Tree::RedBlackNode:0x00..., @key=5, ...>
459
+ ```
460
+ ### max() &#8594; red_black_node
461
+
462
+ Returns the node whose `key` is a maximum in the sub-tree with
463
+ root `self`.
464
+
465
+ Example:
466
+
467
+ ```ruby
468
+ require 'tree/red_black'
469
+
470
+ root = [*0..10].reduce(Tree::RedBlackNode.new) do |acc, v|
471
+ acc.insert_red_black(v)
472
+ end
473
+ root #=> <Tree::RedBlackNode:0x00..., @key=4, ...>
474
+ root.max #=> <Tree::RedBlackNode:0x00..., @key=10, ...>
475
+ root.left #=> <Tree::RedBlackNode:0x00..., @key=2, ...>
476
+ root.left.max #=> <Tree::RedBlackNode:0x00..., @key=3, ...>
477
+ ```
478
+
479
+ ### pred() &#8594; red_black_node
480
+
481
+ Returns the node preceding `self`, or `nil` if no predecessor exists.
482
+ If duplicate keys are allowed, it's possible that `pred.key == key`.
483
+
484
+ Example:
485
+
486
+ ```ruby
487
+ require 'tree/red_black'
488
+
489
+ root = [*1..10].reduce(Tree::RedBlackNode.new) do |acc, v|
490
+ acc.insert_red_black(v)
491
+ end
492
+ root.right.right.key #=> 8
493
+ root.right.right.pred.key #=> 7
494
+ ```
495
+
496
+ ### succ() &#8594; red_black_node
497
+
498
+ Returns the node succeeding `self`, or `nil` if no successor exists.
499
+ If duplicate keys are allowed, it's possible that `succ.key == key`.
500
+
501
+ Example:
502
+
503
+ ```ruby
504
+ require 'tree/red_black'
505
+
506
+ root = [*1..10].reduce(Tree::RedBlackNode.new) do |acc, v|
507
+ acc.insert_red_black(v)
508
+ end
509
+ root.right.right.key #=> 8
510
+ root.right.right.succ.key #=> 9
511
+ ```
512
+
513
+ ### pre_order(&block) &#8594; red_black_node
514
+
515
+ Returns an enumerator for nodes in the tree with root `self` by
516
+ pre-order traversal.
517
+
518
+ Example:
519
+
520
+ ```ruby
521
+ require 'tree/red_black'
522
+
523
+ root = [*1..10].reduce(Tree::RedBlackNode.new) do |acc, v|
524
+ acc.insert_red_black(v)
525
+ end
526
+ root.pre_order.map(&:key) #=> [4, 2, 1, 3, 6, 5, 8, 7, 9, 10]
527
+ ```
528
+
529
+ ### in_order(&block) &#8594; red_black_node
530
+
531
+ Returns an enumerator for nodes in the tree with root `self` by
532
+ in-order traversal.
533
+
534
+ Example:
535
+
536
+ ```ruby
537
+ require 'tree/red_black'
538
+
539
+ root = [*1..10].reduce(Tree::RedBlackNode.new) do |acc, v|
540
+ acc.insert_red_black(v)
541
+ end
542
+ root.in_order.map(&:key) #=> [1, 2, ..., 10]
543
+ ```
544
+
545
+ ### dup() &#8594; red_black_node
546
+
547
+ Returns a deep copy of the tree with root `self`, provided that
548
+ the `dup` method for the `key` attribute of a node is also a
549
+ deep copy.
550
+
551
+ Example:
552
+
553
+ ```ruby
554
+ require 'tree/red_black'
555
+
556
+ root = Tree::RedBlackNode.new({a: 1, b: 2})
557
+ root_copy = root.dup
558
+ p root.key #=> {:a=>1, :b=>2}
559
+ p root.key.delete(:a) #=> 1
560
+ p root.key #=> {:b=>2}
561
+ p root_copy.key #=> {:a=>1, :b=>2}
562
+ ```
563
+
564
+ ## Contributing
565
+
566
+ Bug reports and pull requests can be sent to
567
+ [GitHub tree-red_black](https://github.com/slewsys/tree-red_black).
568
+
569
+ ## License
570
+
571
+ This Rubygem is free software. It can be used and redistributed under
572
+ the terms of the [MIT License](http://opensource.org/licenses/MIT).