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