rooted_tree 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- 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