rooted_tree 0.2.0 → 0.2.1
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.
- checksums.yaml +4 -4
- data/lib/rooted_tree/node.rb +49 -22
- data/lib/rooted_tree/tree.rb +15 -4
- data/lib/rooted_tree/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bf70759dc7a2bf845496a1eb2291a91a4a60e5e2
|
4
|
+
data.tar.gz: 6e7365e5d05e9f8daa1b34e5c726f0d2d8865d1b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 10622361191c35e83775a11d129245eaebc2ce0b69f970e24195dd20bba065784a53a29295446c733d7bd3179b74302a29fe83fd5da6b48fbcfd8c573310db86
|
7
|
+
data.tar.gz: 1e9c114ae888537459a66f2c7b1f27212c2d20160c35a9e84c7a111916c14d20f6042feb585e6430e18cce600a79b0177b7cb0f932e59b26c6f020f8d3ef25f7
|
data/lib/rooted_tree/node.rb
CHANGED
@@ -2,8 +2,12 @@
|
|
2
2
|
|
3
3
|
# Node
|
4
4
|
#
|
5
|
+
# Nodes are mutable by default, since creating anyting but simple leafs would
|
6
|
+
# otherwise be imposible. Calling #freeze on a node makes the entire subtree
|
7
|
+
# immutable. This is used by the Tree class which only operates on frozen node
|
8
|
+
# structures.
|
5
9
|
#
|
6
|
-
# The following is an example of a rooted tree
|
10
|
+
# The following is an example of a rooted tree with maximum depth 2.
|
7
11
|
#
|
8
12
|
# r - r, a, b, c, and d are internal vertices
|
9
13
|
# +--+---+ - vertices e, f, g, h, i, and j are leaves
|
@@ -18,9 +22,14 @@
|
|
18
22
|
|
19
23
|
module RootedTree
|
20
24
|
class Node
|
21
|
-
|
25
|
+
include Enumerable
|
26
|
+
|
27
|
+
attr_accessor :first_child, :last_child, :degree
|
22
28
|
attr_writer :next, :prev, :parent
|
23
|
-
|
29
|
+
|
30
|
+
protected :next=, :prev=, :parent=, :first_child=, :last_child=, :degree=
|
31
|
+
|
32
|
+
alias arity degree
|
24
33
|
|
25
34
|
def initialize
|
26
35
|
@parent = nil
|
@@ -28,6 +37,7 @@ module RootedTree
|
|
28
37
|
@prev = nil
|
29
38
|
@first_child = nil
|
30
39
|
@last_child = nil
|
40
|
+
@degree = 0
|
31
41
|
end
|
32
42
|
|
33
43
|
def initialize_copy(*)
|
@@ -49,7 +59,7 @@ module RootedTree
|
|
49
59
|
# A node is a leaf if it has no children.
|
50
60
|
|
51
61
|
def leaf?
|
52
|
-
@
|
62
|
+
@degree == 0
|
53
63
|
end
|
54
64
|
|
55
65
|
# Internal?
|
@@ -106,16 +116,24 @@ module RootedTree
|
|
106
116
|
end
|
107
117
|
|
108
118
|
alias level depth
|
119
|
+
|
120
|
+
# Max Depth
|
121
|
+
#
|
122
|
+
# Returns the maximum node depth under this node.
|
123
|
+
|
124
|
+
def max_depth offset = depth
|
125
|
+
return offset if leaf?
|
126
|
+
|
127
|
+
children.map {|c| c.max_depth offset + 1 }.max
|
128
|
+
end
|
109
129
|
|
110
|
-
# Degree
|
130
|
+
# Max Degree
|
111
131
|
#
|
112
|
-
# Returns the
|
132
|
+
# Returns the highest child count of the nodes in the subtree.
|
113
133
|
|
114
|
-
def
|
115
|
-
children.
|
134
|
+
def max_degree
|
135
|
+
children.map(&:degree).push(degree).max
|
116
136
|
end
|
117
|
-
|
118
|
-
alias arity degree
|
119
137
|
|
120
138
|
# Size
|
121
139
|
#
|
@@ -167,6 +185,8 @@ module RootedTree
|
|
167
185
|
node.next = @next
|
168
186
|
node.prev = self
|
169
187
|
node.parent = @parent
|
188
|
+
@parent.degree += 1
|
189
|
+
|
170
190
|
if @next
|
171
191
|
@next.prev = node
|
172
192
|
else
|
@@ -185,6 +205,8 @@ module RootedTree
|
|
185
205
|
node.next = self
|
186
206
|
node.prev = @prev
|
187
207
|
node.parent = @parent
|
208
|
+
@parent.degree += 1
|
209
|
+
|
188
210
|
if @prev
|
189
211
|
@prev.next = node
|
190
212
|
else
|
@@ -192,6 +214,13 @@ module RootedTree
|
|
192
214
|
end
|
193
215
|
@prev = node
|
194
216
|
end
|
217
|
+
|
218
|
+
private def add_child_to_leaf(child)
|
219
|
+
@first_child = @last_child = child
|
220
|
+
child.next = child.prev = nil
|
221
|
+
@degree = 1
|
222
|
+
child.parent = self
|
223
|
+
end
|
195
224
|
|
196
225
|
# Append Child
|
197
226
|
#
|
@@ -199,9 +228,7 @@ module RootedTree
|
|
199
228
|
|
200
229
|
def append_child(child)
|
201
230
|
if leaf?
|
202
|
-
|
203
|
-
child.next = child.prev = nil
|
204
|
-
child.parent = self
|
231
|
+
add_child_to_leaf child
|
205
232
|
else
|
206
233
|
@last_child.append_sibling child
|
207
234
|
end
|
@@ -214,9 +241,7 @@ module RootedTree
|
|
214
241
|
|
215
242
|
def prepend_child(child)
|
216
243
|
if leaf?
|
217
|
-
|
218
|
-
child.next = child.prev = nil
|
219
|
-
child.parent = self
|
244
|
+
add_child_to_leaf child
|
220
245
|
else
|
221
246
|
@first_child.prepend_sibling child
|
222
247
|
end
|
@@ -243,6 +268,7 @@ module RootedTree
|
|
243
268
|
@prev.next = @next
|
244
269
|
end
|
245
270
|
|
271
|
+
@parent.degree -= 1
|
246
272
|
@prev = @next = @parent = nil
|
247
273
|
self
|
248
274
|
end
|
@@ -276,11 +302,11 @@ module RootedTree
|
|
276
302
|
|
277
303
|
# Children
|
278
304
|
#
|
279
|
-
#
|
280
|
-
#
|
281
|
-
# be reversed.
|
305
|
+
# Yields to each of the node children. The default order is left-to-right,
|
306
|
+
# but by passing rtl: true the order can be reversed. If a block is not given an enumerator is returned.
|
282
307
|
#
|
283
|
-
#
|
308
|
+
# Note that the block will catch any StopIteration that is raised and
|
309
|
+
# terminate early, returning the value of the exception.
|
284
310
|
|
285
311
|
def children(rtl: false)
|
286
312
|
return to_enum(__callee__, rtl: rtl) unless block_given?
|
@@ -300,7 +326,8 @@ module RootedTree
|
|
300
326
|
|
301
327
|
# Each
|
302
328
|
#
|
303
|
-
#
|
329
|
+
# Yields first to self and then to each child. If a block is not given an
|
330
|
+
# enumerator is returned.
|
304
331
|
|
305
332
|
def each(&block)
|
306
333
|
return to_enum(__callee__) unless block_given?
|
@@ -351,7 +378,7 @@ module RootedTree
|
|
351
378
|
|
352
379
|
def ==(other)
|
353
380
|
return false unless other.is_a? self.class
|
354
|
-
return other.
|
381
|
+
return false unless degree == other.degree
|
355
382
|
|
356
383
|
children.to_a == other.children.to_a
|
357
384
|
end
|
data/lib/rooted_tree/tree.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module RootedTree
|
2
4
|
class Tree
|
3
5
|
attr_reader :root
|
@@ -7,15 +9,24 @@ module RootedTree
|
|
7
9
|
@root.freeze
|
8
10
|
end
|
9
11
|
|
12
|
+
def tree
|
13
|
+
self
|
14
|
+
end
|
15
|
+
|
10
16
|
# Degree
|
11
17
|
#
|
12
18
|
# Returns the maximum degree (number of children) in the tree.
|
13
19
|
|
14
20
|
def degree
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
21
|
+
@degree ||= root.max_degree
|
22
|
+
end
|
23
|
+
|
24
|
+
# Depth
|
25
|
+
#
|
26
|
+
# Returns the maximum depth of the tree.
|
27
|
+
|
28
|
+
def depth
|
29
|
+
@depth ||= root.max_depth
|
19
30
|
end
|
20
31
|
end
|
21
32
|
end
|
data/lib/rooted_tree/version.rb
CHANGED