3
3
module CompSci
4
4
# A CompleteTree can very efficiently use an array for storage using
5
5
# simple arithmetic to determine parent child relationships.
6
+ # Any type of value may be stored in the array / tree at any location.
6
7
#
7
8
class CompleteTree
8
9
class WIP < RuntimeError ; end
9
10
10
- # integer math maps several children to one parent
11
+ # given a child index and child count (e.g. 2 for a binary tree)
12
+ # integer math maps several children to one parent index
11
13
def self . parent_idx ( idx , n )
12
14
( idx -1 ) / n
13
15
end
14
16
17
+ # given a parent index and child count
18
+ # integer math maps several children to one parent index
15
19
def self . children_idx ( idx , n )
16
20
Array . new ( n ) { |i | n *idx + i + 1 }
17
21
end
18
22
23
+ GEN = { }
24
+ [ 2 , 3 , 4 , 5 , 6 ] . each { |n |
25
+ cursor = -1
26
+ GEN [ n ] = Array . new ( 10 ) { |i | cursor += n **i }
27
+ }
28
+
29
+ def self . gen_lookup ( idx , n )
30
+ return nil unless GEN [ n ]
31
+ return nil unless idx <= GEN [ n ] . last
32
+ GEN [ n ] . each . with_index { |max , level | return level if idx <= max }
33
+ nil
34
+ end
35
+
19
36
def self . gen ( idx , n )
20
- count = 0
21
- loop {
22
- pidx = self . parent_idx ( idx , n )
23
- break if pidx < 0
24
- count += 1
25
- idx = pidx
26
- }
27
- count
37
+ return 0 if idx < = 0
38
+ gen_lookup ( idx , n ) or gen ( self . parent_idx ( idx , n ) , n ) + 1
39
+ end
40
+
41
+ # return generation level and sibling count at that level
42
+ def self . generation ( idx , n )
43
+ level = gen ( idx , n )
44
+ [ level , n ** level ]
28
45
end
29
46
30
47
attr_reader :array
@@ -50,65 +67,21 @@ def last_idx
50
67
@array . size - 1 unless @array . empty?
51
68
end
52
69
53
- # or, ya know, just iterate @array
54
- def bf_search ( &blk )
55
- raise ( WIP )
56
- destinations = [ 0 ]
57
- while !destinations . empty?
58
- idx = destinations . shift
59
- return idx if yield @array [ idx ]
60
-
61
- # idx has a val and the block is false
62
- # add existent children to destinations
63
- self . class . children_idx ( idx , @child_slots ) . each { |cidx |
64
- destinations . push ( cidx ) if cidx < @array . size
65
- }
66
- end
67
- end
68
-
69
- def df_search ( &blk )
70
- raise ( WIP )
71
- end
72
-
73
- # TODO: fixme
74
70
def display ( width : 80 )
75
- raise ( WIP )
76
- str = ''
77
- old_level = 0
71
+ result = [ ]
72
+ level = 0
78
73
@array . each_with_index { |val , i |
79
74
val = val . to_s
80
- level = self . class . gen ( i , @child_slots )
81
- if old_level != level
82
- str += NEWLINE
83
- old_level = level
84
- end
75
+ level , slots = self . class . generation ( i , @child_slots )
76
+ block_width = width / slots
85
77
86
78
# center in block_width
87
- slots = @child_slots **level
88
- block_width = width / slots
89
79
space = [ ( block_width + val . size ) / 2 , val . size + 1 ] . max
90
- str += val . ljust ( space , ' ' ) . rjust ( block_width , ' ' )
80
+ result [ level ] ||= ''
81
+ result [ level ] += val . ljust ( space , ' ' ) . rjust ( block_width , ' ' )
91
82
}
92
- str
83
+ result
93
84
end
94
85
alias_method :to_s , :display
95
86
end
96
-
97
- class CompleteBinaryTree < CompleteTree
98
- def initialize ( array : [ ] )
99
- super ( array : array , child_slots : 2 )
100
- end
101
- end
102
-
103
- class CompleteTernaryTree < CompleteTree
104
- def initialize ( array : [ ] )
105
- super ( array : array , child_slots : 3 )
106
- end
107
- end
108
-
109
- class CompleteQuaternaryTree < CompleteTree
110
- def initialize ( array : [ ] )
111
- super ( array : array , child_slots : 4 )
112
- end
113
- end
114
87
end
0 commit comments