ds 0.0.4 → 0.0.6
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 +7 -0
- data/.rubocop.yml +11 -0
- data/.rubocop_todo.yml +452 -0
- data/.travis.yml +12 -0
- data/Gemfile +1 -1
- data/README.rdoc +185 -214
- data/Rakefile +8 -3
- data/ds.gemspec +16 -13
- data/lib/ds.rb +20 -30
- data/lib/ds/{matrixes → arrays}/array_2d.rb +9 -10
- data/lib/ds/arrays/expandable_array.rb +34 -0
- data/lib/ds/arrays/heap_store.rb +32 -0
- data/lib/ds/arrays/tri_matrix.rb +33 -0
- data/lib/ds/lists/list.rb +310 -186
- data/lib/ds/lists/list_element.rb +14 -11
- data/lib/ds/pair.rb +4 -4
- data/lib/ds/queues/priority_queue.rb +33 -20
- data/lib/ds/queues/simple_queue.rb +55 -0
- data/lib/ds/sets/indexed_set.rb +37 -0
- data/lib/ds/stacks/stack.rb +25 -17
- data/lib/ds/trees/binary_heap.rb +71 -66
- data/lib/ds/trees/binary_tree.rb +40 -44
- data/lib/ds/trees/red_black_tree.rb +123 -0
- data/lib/ds/trees/red_black_tree/node.rb +21 -0
- data/lib/ds/trees/tree.rb +50 -48
- data/lib/ds/trees/tree_walker.rb +73 -144
- data/lib/ds/trees/trie.rb +67 -37
- data/lib/ds/trees/trie/node.rb +48 -0
- data/lib/ds/version.rb +2 -1
- data/test/help.rb +3 -6
- data/test/performance/binary_heap_performance_test.rb +20 -0
- data/test/performance/list_performance_test.rb +36 -0
- data/test/performance/priority_queue_performance.rb +32 -0
- data/test/performance/rbt_performance_test.rb +17 -0
- data/test/performance/simple_queue_performance_test.rb +37 -0
- data/test/performance/stack_test.rb +45 -0
- data/test/test_array2d.rb +29 -31
- data/test/test_binary_heap.rb +29 -23
- data/test/test_binary_tree.rb +30 -20
- data/test/test_expandable_array.rb +6 -10
- data/test/test_heap_store.rb +34 -0
- data/test/test_indexed_set.rb +26 -0
- data/test/test_list.rb +226 -109
- data/test/test_list_element.rb +34 -16
- data/test/test_pair.rb +5 -8
- data/test/test_priority_queue.rb +43 -64
- data/test/test_queue.rb +12 -61
- data/test/test_red_black_tree.rb +46 -0
- data/test/test_stack.rb +35 -39
- data/test/test_tree.rb +42 -29
- data/test/test_tree_walker.rb +27 -52
- data/test/test_tri_matrix.rb +6 -11
- data/test/test_trie.rb +59 -17
- metadata +80 -35
- data/lib/ds/ext/array_x.rb +0 -35
- data/lib/ds/graphs/digraph.rb +0 -20
- data/lib/ds/graphs/edge.rb +0 -15
- data/lib/ds/graphs/graph.rb +0 -111
- data/lib/ds/graphs/graph_as_matrix.rb +0 -113
- data/lib/ds/graphs/graph_as_tri_matrix.rb +0 -24
- data/lib/ds/lists/cyclic_list.rb +0 -21
- data/lib/ds/lists/ring.rb +0 -42
- data/lib/ds/matrixes/expandable_array.rb +0 -37
- data/lib/ds/matrixes/tri_matrix.rb +0 -30
- data/lib/ds/queues/queue.rb +0 -53
- data/lib/ds/sets/ordered_set.rb +0 -32
- data/lib/ds/trees/binary_search_tree.rb +0 -34
- data/lib/ds/trees/complete_binary_tree.rb +0 -60
- data/test/test_array_x.rb +0 -51
- data/test/test_binary_search_tree.rb +0 -39
- data/test/test_complete_binary_tree.rb +0 -58
- data/test/test_digraph.rb +0 -134
- data/test/test_graph.rb +0 -80
- data/test/test_ordered_set.rb +0 -28
- data/test/test_ring.rb +0 -28
data/.travis.yml
ADDED
data/Gemfile
CHANGED
data/README.rdoc
CHANGED
@@ -1,39 +1,35 @@
|
|
1
|
-
= DS - Data Structures
|
1
|
+
= DS - Data Structures for Ruby
|
2
2
|
|
3
|
-
|
3
|
+
{<img src="https://travis-ci.org/knife/ds.svg?branch=master" alt="Build Status" />}[https://travis-ci.org/knife/ds]
|
4
4
|
|
5
|
-
|
5
|
+
DS provides some popular data structures not implemented in Ruby natively.
|
6
|
+
|
7
|
+
Data structures included in this gem:
|
6
8
|
|
7
9
|
* Pair
|
8
10
|
* Stacks
|
9
11
|
* Stack
|
10
12
|
* Queues
|
11
|
-
*
|
13
|
+
* SimpleQueue
|
12
14
|
* PriorityQueue
|
13
15
|
* Lists
|
14
16
|
* List
|
15
|
-
* CyclicList
|
16
|
-
* Ring
|
17
17
|
* Trees
|
18
18
|
* Tree
|
19
19
|
* BinaryTree
|
20
|
-
* CompleteBinaryTree
|
21
20
|
* BinaryHeap
|
22
|
-
*
|
21
|
+
* RedBlackTree
|
23
22
|
* Trie
|
24
|
-
* Graphs
|
25
|
-
* Graph
|
26
|
-
* Digraph
|
27
23
|
* Matrixes
|
28
24
|
* Array2D
|
29
25
|
* ExpandableArray
|
30
26
|
* TriMatrix
|
31
27
|
* Sets
|
32
|
-
*
|
28
|
+
* IndexedSet
|
33
29
|
|
34
30
|
|
35
31
|
== Instalation
|
36
|
-
|
32
|
+
|
37
33
|
gem install ds
|
38
34
|
|
39
35
|
== Usage
|
@@ -41,7 +37,8 @@ The DS gem supports the folowing data structures:
|
|
41
37
|
require 'ds'
|
42
38
|
stack = DS::Stack.new
|
43
39
|
|
44
|
-
|
40
|
+
To not have to type "DS::" before each class, use:
|
41
|
+
|
45
42
|
include DS
|
46
43
|
stack = Stack.new
|
47
44
|
|
@@ -50,13 +47,15 @@ The DS gem supports the folowing data structures:
|
|
50
47
|
Pair is simple key-value data structure.
|
51
48
|
|
52
49
|
Creating new Pair
|
53
|
-
p = Pair.new(3,9)
|
50
|
+
p = Pair.new(3, 9)
|
54
51
|
|
55
52
|
Accessors defined on Pair object:
|
56
53
|
|
57
54
|
p.key #=> 3
|
58
|
-
p.first #=> 3
|
59
55
|
p.value #=> 9
|
56
|
+
p.value = 27
|
57
|
+
|
58
|
+
p.first #=> 3
|
60
59
|
p.second #=> 9
|
61
60
|
p.second = 27
|
62
61
|
|
@@ -65,16 +64,21 @@ Accessors defined on Pair object:
|
|
65
64
|
Stack is very simple data structure which allows access only to the top element.
|
66
65
|
More: {Stack}[http://en.wikipedia.org/wiki/Stack_(abstract_data_type)]
|
67
66
|
|
68
|
-
Creating new Stack (implemented as Array).
|
67
|
+
Creating new Stack (implemented as Array).
|
69
68
|
stack = Stack.new
|
69
|
+
with initial values:
|
70
|
+
s = Stack.new(:first, :second)
|
71
|
+
|
72
|
+
Creating new Stack (implemented as List).
|
73
|
+
stack = Stack.create
|
70
74
|
|
71
75
|
The following methods are available on a Stack:
|
72
76
|
|
73
77
|
* push
|
74
78
|
* pop
|
79
|
+
* peek
|
75
80
|
* size
|
76
81
|
* empty?
|
77
|
-
* size
|
78
82
|
|
79
83
|
Examples:
|
80
84
|
stack.empty? #=> true
|
@@ -87,29 +91,29 @@ Examples:
|
|
87
91
|
stack.size #=> 1
|
88
92
|
|
89
93
|
|
90
|
-
|
91
94
|
=== Queues
|
92
95
|
|
93
|
-
|
96
|
+
Queue is First-In-First-Out (FIFO) data structure.
|
94
97
|
Which means that first element added to the queue will be the first one to be removed.
|
95
98
|
More: {Queue}[http://en.wikipedia.org/wiki/Queue_(data_structure)]
|
96
99
|
|
97
100
|
|
98
|
-
====
|
101
|
+
==== SimpleQueue
|
99
102
|
|
100
|
-
Creating new
|
101
|
-
q =
|
103
|
+
Creating new SimpleQueue (implemented as Array).
|
104
|
+
q = SimpleQueue.new
|
105
|
+
with initial values:
|
106
|
+
q = SimpleQueue.new(1, 2, 3)
|
102
107
|
|
103
|
-
Creating new
|
104
|
-
q1 =
|
105
|
-
q1 = Queue.new(:list)
|
108
|
+
Creating new SimpleQueue (implemented as List)
|
109
|
+
q1 = SimpleQueue.create
|
106
110
|
|
107
111
|
The following methods are available on a Queue:
|
108
112
|
|
109
|
-
* enqueue
|
110
|
-
* dequeue
|
113
|
+
* enqueue or push
|
114
|
+
* dequeue or shift
|
111
115
|
* peek
|
112
|
-
* length
|
116
|
+
* length or size
|
113
117
|
* empty?
|
114
118
|
|
115
119
|
Examples:
|
@@ -123,16 +127,27 @@ Examples:
|
|
123
127
|
q.empty? #=> true
|
124
128
|
|
125
129
|
|
126
|
-
==== Priority Queue
|
130
|
+
==== Priority Queue
|
127
131
|
|
128
|
-
PriorityQueue is special form of Queue (PriorityQueue inherits from Queue).
|
129
132
|
In opposite to simple Queue, in PriorityQueue each element is associated with a "priority".
|
130
133
|
More: {Priority Queue}[http://en.wikipedia.org/wiki/Priority_queue]
|
131
134
|
|
132
135
|
Creating new Priority Queue (implemented as BinaryHeap)
|
133
|
-
|
136
|
+
|
134
137
|
q = PriorityQueue.new
|
135
138
|
|
139
|
+
By default higher value means higher priority but you can define own priority
|
140
|
+
order by passing block to constructor:
|
141
|
+
|
142
|
+
PriorityQueue.new { |a, b| a < b }
|
143
|
+
|
144
|
+
|
145
|
+
To add new element to priority queue use #unshift or #push method:
|
146
|
+
q.push(value, priority)
|
147
|
+
|
148
|
+
To remove element from priority queue use #shift or #pop method. The interface
|
149
|
+
is very similar to SimpleQueue.
|
150
|
+
|
136
151
|
Examples:
|
137
152
|
q.push(:important, 3)
|
138
153
|
q.push(:very_important, 5)
|
@@ -145,29 +160,28 @@ Examples:
|
|
145
160
|
q.peek #=> :nevermind
|
146
161
|
|
147
162
|
|
148
|
-
|
149
163
|
=== Lists
|
150
164
|
|
151
165
|
=== List
|
152
166
|
|
153
167
|
List is an ordered collection of values. Each element of list has pointer to the next
|
154
|
-
element (last element points to nil).
|
168
|
+
element (last element points to nil). This implementation uses doubly linked
|
169
|
+
list underhood.
|
155
170
|
More: {List}[http://en.wikipedia.org/wiki/List_(data_structure)]
|
156
171
|
|
157
172
|
Creating new List
|
158
|
-
l = List.new
|
173
|
+
l = List.new
|
159
174
|
l.append(2)
|
160
|
-
or
|
161
|
-
|
162
|
-
list = List.from_array(arr)
|
175
|
+
or
|
176
|
+
list = List.new(1, 2, 3, 4)
|
163
177
|
|
164
178
|
Examples:
|
165
179
|
|
166
|
-
Simple
|
180
|
+
Simple operations on lists
|
167
181
|
list.length #=> 4
|
168
|
-
list.append(5).to_a #=> [1,2,3,4,5]
|
169
|
-
list.
|
170
|
-
list.remove(list.head).to_a #=> [1,2,3,4,5]
|
182
|
+
list.append(5).to_a #=> [1, 2, 3, 4, 5]
|
183
|
+
list.unshift(0).to_a #=> [0, 1, 2, 3, 4, 5]
|
184
|
+
list.remove(list.head).to_a #=> [1, 2, 3, 4, 5]
|
171
185
|
list.shift #=> 1
|
172
186
|
|
173
187
|
Accessing first and last element
|
@@ -177,41 +191,60 @@ Accessing first and last element
|
|
177
191
|
list.first #=> 2
|
178
192
|
list.last #=> 5
|
179
193
|
|
194
|
+
Accessing by index
|
195
|
+
list[2].data #=> 2
|
196
|
+
list.at(2).data #=> 2
|
197
|
+
list[-1].data #=> 4
|
198
|
+
list[1..2].map(&:data) #=> [2, 3]
|
199
|
+
list[1,3].map(&:data) #=> [2, 3, 4]
|
200
|
+
|
201
|
+
Modifying elements on given index:
|
202
|
+
list[2].data = 8
|
203
|
+
list[2].data #=> 8
|
204
|
+
list[2] = [9, 10] #=> [1, 2, 9, 10, 4]
|
205
|
+
list[0,1] = 0 #=> [0, 2, 3, 4]
|
206
|
+
list[2..3] = ['x', 'x'] #=> [1, 2, 'x', 'x']
|
207
|
+
|
208
|
+
|
209
|
+
Checking if given element exists on list
|
210
|
+
list.get(el) #=> el or nil
|
211
|
+
list.get!(el) #=> raises Exception if not found
|
212
|
+
|
180
213
|
Reversing
|
181
|
-
list.reverse!.to_a #=> [5,4,3,1,0]
|
214
|
+
list.reverse!.to_a #=> [5, 4, 3, 1, 0]
|
182
215
|
|
183
216
|
Enumerable methods are also available
|
184
|
-
|
185
|
-
list.map{ |e| e.data } #=> [1,2,3,4]
|
186
|
-
list.inject(0){ |mem, var| mem = mem + var.data } #=> 10
|
187
217
|
|
188
|
-
|
189
|
-
|
190
|
-
* insert_after
|
191
|
-
* zip?
|
192
|
-
* merge
|
218
|
+
list.map{ |e| e.data } #=> [1, 2, 3, 4]
|
219
|
+
list.inject(0){ |a, e| a + e.data } #=> 10
|
193
220
|
|
221
|
+
Append one list to other list
|
222
|
+
list1.concat(list2)
|
194
223
|
|
195
|
-
|
224
|
+
Comparable module is included so you can:
|
196
225
|
|
197
|
-
|
198
|
-
|
226
|
+
Check if lists are equal
|
227
|
+
list1 == list2
|
199
228
|
|
200
|
-
|
201
|
-
|
229
|
+
Check if one list is greater than other (same rules as in Array class)
|
230
|
+
list1 > list2
|
202
231
|
|
203
|
-
Examples:
|
204
|
-
ring.looped? #=> true
|
205
|
-
ring.cycle_size #=> 7
|
206
|
-
ring.eliminate_by(2) #=> 1
|
207
|
-
|
208
232
|
|
233
|
+
Other operations
|
234
|
+
* clone
|
235
|
+
* clear
|
236
|
+
* insert_before
|
237
|
+
* insert_after
|
238
|
+
* zip?
|
239
|
+
* looped?
|
240
|
+
* cycle_size
|
241
|
+
* to_s
|
209
242
|
|
210
243
|
=== Trees
|
211
244
|
|
212
245
|
==== Tree
|
213
246
|
|
214
|
-
A tree is a data structure
|
247
|
+
A tree is a data structure with nodes organised in hierarchy.
|
215
248
|
More: {Tree}[http://en.wikipedia.org/wiki/Tree_(data_structure)]
|
216
249
|
|
217
250
|
Building Tree
|
@@ -225,259 +258,198 @@ Building Tree
|
|
225
258
|
c1 << 10
|
226
259
|
c3 = c2 << 3
|
227
260
|
|
228
|
-
|
261
|
+
Methods:
|
229
262
|
t.leaf? #=> false
|
230
263
|
c3.leaf? #=> true
|
231
264
|
|
265
|
+
c1.sibblings.map &:data #=> [8, 9]
|
266
|
+
c1.parent.data #=> 2
|
267
|
+
|
232
268
|
t.height #=> 3
|
233
269
|
t.width #=> 3
|
234
270
|
t.leaf_count #=> 4
|
235
|
-
|
236
|
-
t.levels #=> {1=>1,2=>3, 3=>3}
|
271
|
+
|
272
|
+
t.levels #=> {1=>1, 2=>3, 3=>3}
|
237
273
|
|
238
274
|
Other methods
|
239
275
|
* get_leaves
|
240
276
|
* isometric?
|
241
277
|
* mirror!
|
242
278
|
|
243
|
-
Enumerable Module is included.
|
244
|
-
t.map{ |node| node.data } #=> [2,5,8,9,4,10,3]
|
279
|
+
Enumerable Module is also included.
|
280
|
+
t.map { |node| node.data } #=> [2, 5, 8, 9, 4, 10, 3]
|
245
281
|
|
246
282
|
|
247
283
|
==== Binary Tree
|
248
284
|
|
249
|
-
BinaryTree is sublass of Tree
|
285
|
+
BinaryTree is sublass of Tree. In BinaryTree each node can have at most two children.
|
250
286
|
More: {BinaryTree}[http://en.wikipedia.org/wiki/Binary_tree]
|
251
287
|
|
252
288
|
Building tree
|
253
289
|
bin_tree = BinaryTree.new
|
254
|
-
[2,5,8,9,11,12,14].each{|x| bin_tree.insert(x)} #
|
290
|
+
[2, 5, 8, 9, 11, 12, 14].each { |x| bin_tree.insert(x) } #builds complete binary Tree
|
255
291
|
|
256
292
|
Accessors defined on BinaryTree object:
|
257
|
-
bin_tree.left #=> 5
|
258
|
-
bin_tree.right #=> 8
|
293
|
+
bin_tree.left.data #=> 5
|
294
|
+
bin_tree.right.data #=> 8
|
259
295
|
|
260
296
|
|
261
|
-
====
|
297
|
+
==== Red Black Tree
|
262
298
|
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
* Both the left and right subtrees must also be binary search trees.
|
299
|
+
Red-black tree is symbol table data structure. It's very simmilar to hash, but internally
|
300
|
+
uses tree (perfect balanced binary tree) and not depends on hash function. Red
|
301
|
+
black trees aren't as fast as hashes but supports ordered operations.
|
267
302
|
|
268
|
-
|
269
|
-
|
303
|
+
rb = RedBlackTree.new
|
304
|
+
rb.insert(:z, 3)
|
305
|
+
rb.insert(:p, 2)
|
306
|
+
rb.insert(:a, 1)
|
307
|
+
rb.get(:a) #=> 1
|
270
308
|
|
271
|
-
|
272
|
-
|
273
|
-
walker.traverse(:inorder).must_equal [1,2,3,5,6,7,8]
|
309
|
+
You can also create RBT by passing hash to constructor
|
310
|
+
rb = RedBlackTree.new(a: 1, p: 2, z: 3)
|
274
311
|
|
312
|
+
Hash like accessors are defined
|
275
313
|
|
276
|
-
|
314
|
+
rb[:z] = 3
|
315
|
+
rb[:z] #=> 3
|
277
316
|
|
278
|
-
|
279
|
-
|
280
|
-
CompleteBinaryTree is binary tree but does not inherit from Tree and BinaryTree class! Nodes are stored
|
281
|
-
internally in array.
|
282
|
-
More: {Complete Binary Tree}[http://en.wikipedia.org/wiki/Complete_binary_tree]
|
283
|
-
|
284
|
-
Creating
|
285
|
-
cbt = CompleteBinaryTree.new(1,2,3,4,5,6,7)
|
286
|
-
|
287
|
-
Examples
|
288
|
-
cbt.root #=> 1
|
289
|
-
cbt.left(0) #=> 2
|
290
|
-
cbt.right(0) #=> 3
|
291
|
-
cbt.parent(1) #=> 0
|
292
|
-
|
293
|
-
cbt.left_index(0) #=> 1
|
294
|
-
cbt.right_index(1) #=> 4
|
295
|
-
cpt.parent_index(1) #=> 0
|
317
|
+
You can convert RedBlackTree to Hash with to_h method:
|
318
|
+
rb.to_h #=> {a: 1, p: 2, z: 3}
|
296
319
|
|
320
|
+
Enumerable is included and traversing is ordered by key
|
321
|
+
rb.map(&:key) #=> [:a, :p, :z]
|
297
322
|
|
298
323
|
==== Binary Heap
|
299
324
|
|
300
|
-
BinaryHeap is
|
301
|
-
access to maximum or minimum element of the tree.
|
325
|
+
BinaryHeap is tree in which every node satisfies heap property. Binary Heap allows very fast
|
326
|
+
access to maximum or minimum element of the tree (const access).
|
302
327
|
More: {Binary Heap}[http://en.wikipedia.org/wiki/Binary_heap]
|
303
328
|
|
304
329
|
Creating
|
305
330
|
|
306
|
-
Maximum Binary Heap
|
307
|
-
max_heap = BinaryHeap.new(9,8,4,5,11,6)
|
331
|
+
Maximum Binary Heap
|
332
|
+
max_heap = BinaryHeap.new(9, 8, 4, 5, 11, 6)
|
308
333
|
or
|
309
|
-
max_heap = BinaryHeap.max(9,8,4,5,11,6)
|
334
|
+
max_heap = BinaryHeap.max(9, 8, 4, 5, 11, 6)
|
310
335
|
|
311
336
|
Minimum Binary Heap
|
312
|
-
min_heap = BinaryHeap.min(9,8,4,5,11,6)
|
337
|
+
min_heap = BinaryHeap.min(9, 8, 4, 5, 11, 6)
|
313
338
|
or
|
314
|
-
BinaryHeap.new(9,8,4,5,11,6){|parent,child| parent < child}
|
339
|
+
BinaryHeap.new(9, 8, 4, 5, 11, 6){ |parent, child| parent < child }
|
315
340
|
|
316
341
|
You can set heap relation by passing block to BinaryHeap constructor.
|
317
342
|
|
318
343
|
Examples
|
319
344
|
max_heap.shift #returns max element (11)
|
320
|
-
max_heap.to_a #=> [9,8,6,5,4]
|
345
|
+
max_heap.to_a #=> [9, 8, 6, 5, 4]
|
321
346
|
max_heap.insert 15
|
322
347
|
max_heap.shift #=> 15
|
323
348
|
|
324
349
|
min_heap.shift #returns min element (4)
|
325
350
|
|
326
351
|
|
327
|
-
==== Trie
|
352
|
+
==== Trie
|
328
353
|
|
329
354
|
Trie is an ordered tree data structure which allows very quick search: O(k), where k is word length.
|
330
355
|
More: {Trie}[http://en.wikipedia.org/wiki/Trie]
|
331
356
|
|
332
|
-
Creating
|
357
|
+
Creating
|
333
358
|
trie = Trie.new
|
334
|
-
|
359
|
+
|
360
|
+
Setting custom alphabet (memory usage depends on alphabet size)
|
361
|
+
trie.alphabet = %w(a b c d)
|
362
|
+
|
335
363
|
Examples
|
336
|
-
trie.insert(
|
337
|
-
trie.find(
|
364
|
+
trie.insert('thing', true);
|
365
|
+
trie.find('thing') # => true
|
366
|
+
trie.delete('thing')
|
367
|
+
or
|
368
|
+
trie['one'] = 'thing'
|
369
|
+
trie['one'] # => 'thing'
|
370
|
+
|
371
|
+
Enumerable module is included so you can iterate through trie:
|
372
|
+
trie.map { |k, v| [k, v] } # => [['he', true], ['hello', true], ['help', true]]
|
338
373
|
|
374
|
+
Finding all words matching given prefix:
|
375
|
+
trie.with_prefix('th') # => ['the', 'thing']
|
376
|
+
trie.with_prefix('yeti') # => []
|
339
377
|
|
340
|
-
|
378
|
+
Alternatively you can pass block to this method:
|
379
|
+
trie.with_prefix('th'){ |word, val| res[word] = val } # => {'the' => true, 'thing' => true}
|
341
380
|
|
342
|
-
|
343
|
-
[2,5,8,9,11,12,14].each{|x| b.insert(x)}
|
381
|
+
==== Tree Traversals
|
344
382
|
|
345
|
-
|
383
|
+
b = BinaryTree.new
|
384
|
+
[2, 5, 8, 9, 11, 12, 14].each{ |x| b.insert(x) }
|
385
|
+
|
386
|
+
walker = TreeWalker.new(b)
|
346
387
|
|
347
|
-
Iterating in postorder
|
348
|
-
walker.traverse(:postorder) #=> [9,11,5,12,14,8,2]
|
388
|
+
Iterating in postorder
|
389
|
+
walker.traverse(:postorder) #=> [9, 11, 5, 12, 14, 8, 2]
|
349
390
|
Iterating in inorder
|
350
|
-
walker.traverse(:inorder) #=> [9,5,11,2,12,8,14]
|
391
|
+
walker.traverse(:inorder) #=> [9, 5, 11, 2, 12, 8, 14]
|
351
392
|
Iterating in preorder
|
352
|
-
walker.traverse(:preorder) #=> [2,5,9,11,8,12,14]
|
393
|
+
walker.traverse(:preorder) #=> [2, 5, 9, 11, 8, 12, 14]
|
353
394
|
|
354
395
|
Iterating in BFS order
|
355
|
-
walker.each{ |x| x } #=> [2,5,8,9,11,12,14]
|
396
|
+
walker.each{ |x| x } #=> [2, 5, 8, 9, 11, 12, 14]
|
356
397
|
|
357
398
|
|
358
399
|
You can also pass block to traverse method
|
359
|
-
walker.traverse(:inorder){|n|
|
400
|
+
walker.traverse(:inorder){ |n| n.data**2 }
|
360
401
|
|
361
402
|
If you want to change value of tree nodes, use recalculate! method
|
362
|
-
walker.recalculate!(b
|
403
|
+
walker.recalculate!(b, :preorder, 0) { |e, a| a + e.data }
|
363
404
|
|
364
405
|
|
365
|
-
|
366
|
-
=== Graphs
|
367
|
-
|
368
|
-
A graph data structure consists of a finite (and possibly mutable) set of
|
369
|
-
ordered pairs, called edges or arcs, of certain entities called nodes or
|
370
|
-
vertices.
|
371
|
-
More: {Graph}[http://en.wikipedia.org/wiki/Graph_(data_structure)]
|
372
|
-
|
373
|
-
|
374
|
-
====Graph
|
375
|
-
|
376
|
-
Creating new Graph
|
377
|
-
|
378
|
-
edges = []
|
379
|
-
edges << Edge.new('Lukas','Marc')
|
380
|
-
edges << Edge.new('Lukas','Tom')
|
381
|
-
edges << Edge.new('Marc','Jack')
|
382
|
-
edges << Edge.new('Tom','Marc')
|
383
|
-
|
384
|
-
New graph implemented as Triangular Matrix
|
385
|
-
graph = Graph.create(edges)
|
386
|
-
|
387
|
-
New graph implemented as Matrix
|
388
|
-
graph = Graph.new(edges,:matrix)
|
389
|
-
|
390
|
-
|
391
|
-
Examples:
|
392
|
-
|
393
|
-
graph.vertex_size #=> 4
|
394
|
-
graph.degree("Marc") #=> 3
|
395
|
-
graph.edge?("Marc","Tom") #=> true
|
396
|
-
graph.edge?("Tom","Jack") #=> false
|
397
|
-
graph.add_edges([Edge.new("Marc","Kate")])
|
398
|
-
graph.remove("Marc","Jack")
|
399
|
-
graph.neighbors('Tom') #=> ["Marc","Lucas"]
|
400
|
-
|
401
|
-
Iterating
|
402
|
-
graph.each_edge{|e| p e}
|
403
|
-
graph.each_vertex{ |v| p v }
|
404
|
-
|
405
|
-
|
406
|
-
==== Digraph
|
407
|
-
|
408
|
-
Creating Directed Weighted Graph is simple like that:
|
409
|
-
|
410
|
-
edges = []
|
411
|
-
|
412
|
-
edges << Edge.new(:A,:C,5)
|
413
|
-
edges << Edge.new(:A,:D,3)
|
414
|
-
edges << Edge.new(:A,:G,14)
|
415
|
-
edges << Edge.new(:C,:E,3)
|
416
|
-
edges << Edge.new(:C,:F,2)
|
417
|
-
edges << Edge.new(:D,:C,11)
|
418
|
-
edges << Edge.new(:D,:E,7)
|
419
|
-
edges << Edge.new(:D,:G,6)
|
420
|
-
edges << Edge.new(:G,:E,7)
|
421
|
-
edges << Edge.new(:E,:B,5)
|
422
|
-
edges << Edge.new(:G,:B,6)
|
423
|
-
edges << Edge.new(:F,:B,7)
|
424
|
-
|
425
|
-
wdigraph = Digraph.create(edges)
|
426
|
-
|
427
|
-
Examples
|
428
|
-
wdigraph.get_edge(:D,:C).weight #=> 11
|
429
|
-
wdigraph.degree(:E) #=> 4
|
430
|
-
wdigraph.in_degree(:E) #=> 3
|
431
|
-
wdigraph.out_degree(:E) #=> 1
|
432
|
-
wdigraph.bfs(:A) #=> [:A, :C, :D, :G, :E, :F, :B]
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
=== Matrixes
|
406
|
+
=== Arrays
|
438
407
|
|
439
408
|
==== Array2D
|
440
409
|
|
441
|
-
Simple two dimensional array(matrix).
|
410
|
+
Simple two dimensional array(matrix).
|
442
411
|
Array2D extends automatically like simple Array.
|
443
412
|
|
444
413
|
Creating
|
445
|
-
discrete_matrix = Array2D.new(2,0)
|
414
|
+
discrete_matrix = Array2D.new(2, 0)
|
446
415
|
|
447
|
-
|
448
|
-
discrete_matrix.to_a #=> [[0,0],[0,0]]
|
449
|
-
discrete_matrix[3,3] #=> 0
|
416
|
+
First argument is size of row(or column) and second is default value of matrix.
|
450
417
|
|
418
|
+
Examples
|
419
|
+
discrete_matrix.to_a #=> [[0, 0], [0, 0]]
|
420
|
+
discrete_matrix[3, 3] #=> 0
|
451
421
|
|
452
422
|
|
453
423
|
==== ExpandableArray
|
454
424
|
|
455
|
-
|
456
|
-
|
425
|
+
Automaticaly fills empty slots with custom value:
|
426
|
+
|
427
|
+
arr = ExpandableArray.new(0, 0)
|
428
|
+
arr[4] = 1 #=> [0, 0, 0, 0, 4]
|
457
429
|
|
458
430
|
|
459
431
|
==== TriMatrix
|
460
432
|
Triangular matrix is a special kind of matrix where M[x,y] = M[y,x].
|
461
|
-
More: {Triangular
|
433
|
+
More: {Triangular Matrix}[http://en.wikipedia.org/wiki/Triangular_matrix]
|
462
434
|
|
463
435
|
Creating
|
464
436
|
tri_matrix = TriMatrix.new
|
465
|
-
tri_matrix[0,1] = true
|
466
|
-
tri_matrix[0,2] = true
|
437
|
+
tri_matrix[0, 1] = true
|
438
|
+
tri_matrix[0, 2] = true
|
467
439
|
|
468
440
|
Examples
|
469
|
-
tri_matrix[0,1] == tri_matrix[1,0] #=> true
|
441
|
+
tri_matrix[0, 1] == tri_matrix[1, 0] #=> true
|
470
442
|
|
471
443
|
|
472
444
|
|
473
445
|
=== Sets
|
474
446
|
|
475
|
-
====
|
476
|
-
|
477
|
-
are not allowed.
|
447
|
+
==== IndexedSet
|
448
|
+
IndexedSet is a set whose elements are indexed. In opposite to Array, duplicates
|
449
|
+
are not allowed. Internally uses hash for fast access and array for ordering.
|
478
450
|
|
479
|
-
Creating new
|
480
|
-
set =
|
451
|
+
Creating new Indexed Set
|
452
|
+
set = IndexedSet.new
|
481
453
|
|
482
454
|
Examples
|
483
455
|
set.push(:first) #=> 0
|
@@ -485,4 +457,3 @@ Examples
|
|
485
457
|
set.index(:first) #=> 0
|
486
458
|
set.to_a #=> [:first, :second]
|
487
459
|
|
488
|
-
|