RubyDataStructures 0.0.4 → 1.0.0
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.
- data/README.md +193 -0
- data/lib/RubyDataStructures/max_heap.rb +101 -0
- data/lib/RubyDataStructures/version.rb +1 -1
- data/lib/RubyDataStructures.rb +2 -1
- data/test/max_heap_test.rb +46 -0
- metadata +7 -10
- data/README +0 -3
data/README.md
ADDED
@@ -0,0 +1,193 @@
|
|
1
|
+
RubyDatStructures
|
2
|
+
=============
|
3
|
+
|
4
|
+
`RubyDataStructures` gem is a `ruby` implementation of common data structures that are not by default supported by the Ruby programming language.
|
5
|
+
The `RubyDatStructures` supports the following data structures:
|
6
|
+
|
7
|
+
- Multi Dimensional Array
|
8
|
+
- Stack (Implemented as an array)
|
9
|
+
- Queue (Implemented as an array)
|
10
|
+
- Singly Linked List
|
11
|
+
- Doubly Linked List
|
12
|
+
- Max Heap
|
13
|
+
|
14
|
+
Installation
|
15
|
+
------------
|
16
|
+
|
17
|
+
gem install RubyDataStructures
|
18
|
+
|
19
|
+
Usage
|
20
|
+
-----
|
21
|
+
|
22
|
+
The `RubyDatStructures` library can be easily imported by running:
|
23
|
+
|
24
|
+
require 'rubygems'
|
25
|
+
require 'RubyDatStructures'
|
26
|
+
|
27
|
+
The usage of each of the data structures is described below.
|
28
|
+
|
29
|
+
## Multi Dimensional Array
|
30
|
+
|
31
|
+
A `multi dimensional array` can be initialized by running:
|
32
|
+
|
33
|
+
RubyDataStructures::MultiDimensionalArray.new(n)
|
34
|
+
|
35
|
+
where `n` is the number of dimensions of the multi dimensional array.
|
36
|
+
|
37
|
+
The key at a particular index can be easily accessed by calling the array with the dimensions of the index.
|
38
|
+
The key at the index with dimensions `(2,4,3)` of a multi dimensional array `mul_dim_array` can be access by calling:
|
39
|
+
|
40
|
+
mul_dim_array[2,4,3]
|
41
|
+
|
42
|
+
The key for an index can also be easily set by calling the setter with the dimensions of the index.
|
43
|
+
The key at the index with dimensions `(2,4,3)` of a multi dimensional array `mul_dim_array` can be set to `36` by calling:
|
44
|
+
|
45
|
+
mul_dim_array[2,4,3] = 36
|
46
|
+
|
47
|
+
## Stack
|
48
|
+
|
49
|
+
A `Stack` can be initialized by running:
|
50
|
+
|
51
|
+
RubyDataStructures::StackAsArray.new(n)
|
52
|
+
|
53
|
+
where `n` is the max-size of stack.
|
54
|
+
|
55
|
+
The following methods available on a `stack` are self explanatory:
|
56
|
+
|
57
|
+
- empty?
|
58
|
+
- full?
|
59
|
+
- singleton?
|
60
|
+
- push(`element`)
|
61
|
+
- pop
|
62
|
+
- reset
|
63
|
+
|
64
|
+
Examples:
|
65
|
+
|
66
|
+
my_stack = RubyDataStructures::StackAsArray.new(5)
|
67
|
+
my_stack.empty? # Returns `true`
|
68
|
+
my_stack.full? # Returns `false`
|
69
|
+
my_stack.singleton? # Returns `false`
|
70
|
+
my_stack.push(1)
|
71
|
+
my_stack.push(2)
|
72
|
+
my_stach.push(3)
|
73
|
+
my_stack.pop # Return `3`
|
74
|
+
|
75
|
+
## Queue
|
76
|
+
|
77
|
+
A `Queue` can be initialized by calling:
|
78
|
+
|
79
|
+
RubyDataStructures::QueueAsArray.new(n)
|
80
|
+
|
81
|
+
where `n` is the max-size of the queue.
|
82
|
+
|
83
|
+
The following methods available on a `queue` are self explanatory:
|
84
|
+
|
85
|
+
- empty?
|
86
|
+
- full?
|
87
|
+
- enqueue(`element`)
|
88
|
+
- dequeue
|
89
|
+
- reset
|
90
|
+
|
91
|
+
Examples:
|
92
|
+
|
93
|
+
my_queue = RubyDataStructures::QueueAsArray.new(5)
|
94
|
+
my_queue.empty? # Returns `true`
|
95
|
+
my_queue.full? # Returns `false`
|
96
|
+
my_queue.enqueue(1)
|
97
|
+
my_queue.enqueue(2)
|
98
|
+
my_queue.enqueue(3)
|
99
|
+
my_queue.dequeue # Returns `1`
|
100
|
+
|
101
|
+
## Singly Linked List
|
102
|
+
|
103
|
+
A `singly linked list` can be initialized by running:
|
104
|
+
|
105
|
+
RubyDataStructures::SinglyLinkedList.new
|
106
|
+
|
107
|
+
The following methods available on a `singly linked list` are self explanatory:
|
108
|
+
|
109
|
+
- head
|
110
|
+
- empty?
|
111
|
+
- insert(`item`)
|
112
|
+
- search(`key`)
|
113
|
+
- delete(`key`)
|
114
|
+
- reset
|
115
|
+
|
116
|
+
Examples:
|
117
|
+
|
118
|
+
my_list = RubyDataStructures::SinglyLinkedList.new
|
119
|
+
my_list.head # Returns `nil`
|
120
|
+
my_list.empty? # Returns `true`
|
121
|
+
my_list.insert(7)
|
122
|
+
my_list.search(7) # Returns a `RubyDataStructures::SinglyLinkedList::Element` element, whose key is `7`
|
123
|
+
my_list.delete(7)
|
124
|
+
|
125
|
+
## Doubly Linked List
|
126
|
+
|
127
|
+
A `doubly linked list` can be intialized by running:
|
128
|
+
|
129
|
+
RubyDataStructures::DoublyLinkedList.new
|
130
|
+
|
131
|
+
The following methods available on a `doubly linked list` are self explanatory:
|
132
|
+
|
133
|
+
- head
|
134
|
+
- tail
|
135
|
+
- empty?
|
136
|
+
- insert(`item`)
|
137
|
+
- search(`key`)
|
138
|
+
- delete(`key`)
|
139
|
+
- reset
|
140
|
+
|
141
|
+
Examples:
|
142
|
+
|
143
|
+
my_list = RubyDataStructures::DoublyLinkedList.new
|
144
|
+
my_list.head # Returns a `RubyDataStructures::DoublyLinkedList::Element` element, whose key is nil
|
145
|
+
my_list.tail # Returns a `RubyDataStructures::DoublyLinkedList::Element` element, whose key is nil
|
146
|
+
my_list.empty? # Returns `true`
|
147
|
+
my_list.insert(7)
|
148
|
+
my_list.search(7) # Returns a `RubyDataStructures::DoublyLinkedList::Element` element, whose key is `7`
|
149
|
+
my_list.delete(7)
|
150
|
+
|
151
|
+
## Max Heap
|
152
|
+
|
153
|
+
`MaxHeap` inherits most of its functionality from `Array`.
|
154
|
+
A `max heap` can be initialized by running:
|
155
|
+
|
156
|
+
RubyDataStructures::MaxHeap.build(array)
|
157
|
+
|
158
|
+
where `array` is an array, out of which we would like to build a max heap.
|
159
|
+
|
160
|
+
For example, a heap can be built out of an array `[4, 1, 3, 2, 16, 9, 10, 14, 8, 7]` by running:
|
161
|
+
|
162
|
+
heap = RubyDataStructures::MaxHeap.build([4, 1, 3, 2, 16, 9, 10, 14, 8, 7])
|
163
|
+
# Returns the MaxHeap: [16, 14, 10, 8, 7, 9, 3, 2, 4, 1]
|
164
|
+
|
165
|
+
The `maximum` of the heap can be accessed by running:
|
166
|
+
|
167
|
+
heap.maximum # Returns `16`
|
168
|
+
|
169
|
+
The maximum of the heap can be extracted by running:
|
170
|
+
|
171
|
+
heap.extract_maximum!
|
172
|
+
|
173
|
+
The key of a particular element can be increased by running:
|
174
|
+
|
175
|
+
heap.increase_key!(index, key)
|
176
|
+
|
177
|
+
Example:
|
178
|
+
|
179
|
+
heap.increase_key!(8, 15)
|
180
|
+
|
181
|
+
A key can be inserted into a heap by running:
|
182
|
+
|
183
|
+
heap.insert!(key)
|
184
|
+
|
185
|
+
Example:
|
186
|
+
|
187
|
+
heap.insert!(11)
|
188
|
+
|
189
|
+
|
190
|
+
Author
|
191
|
+
------
|
192
|
+
|
193
|
+
B V Satyaram <[bvsatyaram.com](http://bvsatyaram.com)>
|
@@ -0,0 +1,101 @@
|
|
1
|
+
class RubyDataStructures::MaxHeap < Array
|
2
|
+
Infinity = 1.0/0
|
3
|
+
|
4
|
+
attr_accessor :heapsize
|
5
|
+
|
6
|
+
# It is assumed that the binary trees rooted at left(i) and right(i) are max heaps,
|
7
|
+
# but self[i] might be smaller than its children, thus violating the max-heap property.
|
8
|
+
# max_heapify! lets the value at self[i] float down in the max-heap,
|
9
|
+
# so that the subtree rooted at index i obeys the max-heap property
|
10
|
+
def max_heapify!(i)
|
11
|
+
l = left(i)
|
12
|
+
r = right(i)
|
13
|
+
|
14
|
+
if l < self.heapsize && self[l] > self[i]
|
15
|
+
largest = l
|
16
|
+
else
|
17
|
+
largest = i
|
18
|
+
end
|
19
|
+
|
20
|
+
if r < self.heapsize && self[r] > self[largest]
|
21
|
+
largest = r
|
22
|
+
end
|
23
|
+
|
24
|
+
if largest != i
|
25
|
+
exchange(i, largest)
|
26
|
+
max_heapify!(largest)
|
27
|
+
end
|
28
|
+
|
29
|
+
return self
|
30
|
+
end
|
31
|
+
|
32
|
+
# Builds a max-heap from an array
|
33
|
+
def self.build(array)
|
34
|
+
heap = self.new(array)
|
35
|
+
heap.heapsize = array.size
|
36
|
+
|
37
|
+
if heap.heapsize > 0
|
38
|
+
((heap.heapsize/2) - 1).downto(0) do |i|
|
39
|
+
heap.max_heapify!(i)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
return heap
|
44
|
+
end
|
45
|
+
|
46
|
+
# Returns the maximum element of the heap
|
47
|
+
def maximum
|
48
|
+
return self[0]
|
49
|
+
end
|
50
|
+
|
51
|
+
# Extracts the maximum of the heap and max_heapifies the remaining heap.
|
52
|
+
# Returns the maximum of the input heap
|
53
|
+
def extract_maximum!
|
54
|
+
raise "Heap Underflow - The heap is empty" if self.heapsize < 1
|
55
|
+
|
56
|
+
max_value = self[0]
|
57
|
+
self[0] = self[self.heapsize - 1]
|
58
|
+
self.heapsize = self.heapsize - 1
|
59
|
+
self.max_heapify!(0)
|
60
|
+
|
61
|
+
return max_value
|
62
|
+
end
|
63
|
+
|
64
|
+
def increase_key!(i, key)
|
65
|
+
raise "New key is smaller than the current key" if key < self[i]
|
66
|
+
|
67
|
+
self[i] = key
|
68
|
+
while (i > 0) && (self[parent(i)] < self[i])
|
69
|
+
exchange(i, parent(i))
|
70
|
+
i = parent(i)
|
71
|
+
end
|
72
|
+
|
73
|
+
return self
|
74
|
+
end
|
75
|
+
|
76
|
+
def insert!(key)
|
77
|
+
self.heapsize = self.heapsize + 1
|
78
|
+
self[self.heapsize - 1] = -Infinity
|
79
|
+
self.increase_key!(self.heapsize - 1, key)
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
def parent(i)
|
85
|
+
return ((i+1)/2) - 1
|
86
|
+
end
|
87
|
+
|
88
|
+
def left(i)
|
89
|
+
return (2*i) + 1
|
90
|
+
end
|
91
|
+
|
92
|
+
def right(i)
|
93
|
+
return (2*i) + 2
|
94
|
+
end
|
95
|
+
|
96
|
+
def exchange(i, j)
|
97
|
+
tmp = self[i]
|
98
|
+
self[i] = self[j]
|
99
|
+
self[j] = tmp
|
100
|
+
end
|
101
|
+
end
|
data/lib/RubyDataStructures.rb
CHANGED
@@ -8,4 +8,5 @@ require 'RubyDataStructures/queue_as_array'
|
|
8
8
|
require 'RubyDataStructures/singly_linked_list'
|
9
9
|
require 'RubyDataStructures/singly_linked_list/element'
|
10
10
|
require 'RubyDataStructures/doubly_linked_list'
|
11
|
-
require 'RubyDataStructures/doubly_linked_list/element'
|
11
|
+
require 'RubyDataStructures/doubly_linked_list/element'
|
12
|
+
require 'RubyDataStructures/max_heap'
|
@@ -0,0 +1,46 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__),'..','lib')
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'RubyDataStructures'
|
5
|
+
|
6
|
+
class MaxHeapTest < Test::Unit::TestCase
|
7
|
+
def test_build
|
8
|
+
assert_equal [16, 14, 10, 8, 7, 9, 3, 2, 4, 1], RubyDataStructures::MaxHeap.build([4, 1, 3, 2, 16, 9, 10, 14, 8, 7])
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_maximum
|
12
|
+
array = [4, 1, 3, 2, 16, 9, 10, 14, 8, 7]
|
13
|
+
heap = RubyDataStructures::MaxHeap.build(array)
|
14
|
+
|
15
|
+
assert_equal 16, heap.maximum
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_extract_maximum
|
19
|
+
array = [4, 1, 3, 2, 16, 9, 10, 14, 8, 7]
|
20
|
+
heap = RubyDataStructures::MaxHeap.build(array)
|
21
|
+
|
22
|
+
assert_equal 10, heap.heapsize
|
23
|
+
assert_equal 16, heap.extract_maximum!
|
24
|
+
assert_equal 9, heap.heapsize
|
25
|
+
assert_equal [14, 8, 10, 4, 7, 9, 3, 2, 1, 1], heap
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_increase_key
|
29
|
+
array = [4, 1, 3, 2, 16, 9, 10, 14, 8, 7]
|
30
|
+
heap = RubyDataStructures::MaxHeap.build(array)
|
31
|
+
|
32
|
+
assert_equal [16, 15, 10, 14, 7, 9, 3, 2, 8, 1], heap.increase_key!(8, 15)
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_insert
|
36
|
+
array = [4, 1, 3, 2, 16, 9, 10, 14, 8, 7]
|
37
|
+
heap = RubyDataStructures::MaxHeap.build(array)
|
38
|
+
|
39
|
+
assert_equal 10, heap.heapsize
|
40
|
+
assert_equal 16, heap.extract_maximum!
|
41
|
+
assert_equal 9, heap.heapsize
|
42
|
+
assert_equal [14, 8, 10, 4, 7, 9, 3, 2, 1, 1], heap
|
43
|
+
|
44
|
+
assert_equal [14, 11, 10, 4, 8, 9, 3, 2, 1, 7], heap.insert!(11)
|
45
|
+
end
|
46
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: RubyDataStructures
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash: 23
|
5
4
|
prerelease: false
|
6
5
|
segments:
|
6
|
+
- 1
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
|
10
|
-
version: 0.0.4
|
9
|
+
version: 1.0.0
|
11
10
|
platform: ruby
|
12
11
|
authors:
|
13
12
|
- Satyaram B V
|
@@ -15,7 +14,7 @@ autorequire:
|
|
15
14
|
bindir: bin
|
16
15
|
cert_chain: []
|
17
16
|
|
18
|
-
date: 2011-
|
17
|
+
date: 2011-05-16 00:00:00 +05:30
|
19
18
|
default_executable:
|
20
19
|
dependencies: []
|
21
20
|
|
@@ -32,13 +31,14 @@ files:
|
|
32
31
|
- .gitignore
|
33
32
|
- Gemfile
|
34
33
|
- LICENSE
|
35
|
-
- README
|
34
|
+
- README.md
|
36
35
|
- RELEASE_NOTES
|
37
36
|
- Rakefile
|
38
37
|
- RubyDataStructures.gemspec
|
39
38
|
- lib/RubyDataStructures.rb
|
40
39
|
- lib/RubyDataStructures/doubly_linked_list.rb
|
41
40
|
- lib/RubyDataStructures/doubly_linked_list/element.rb
|
41
|
+
- lib/RubyDataStructures/max_heap.rb
|
42
42
|
- lib/RubyDataStructures/multi_dimensional_array.rb
|
43
43
|
- lib/RubyDataStructures/queue_as_array.rb
|
44
44
|
- lib/RubyDataStructures/ruby_data_structures.rb
|
@@ -49,6 +49,7 @@ files:
|
|
49
49
|
- test/RubyDataStructureTest.rb
|
50
50
|
- test/doubly_linked_list_element_test.rb
|
51
51
|
- test/doubly_linked_list_test.rb
|
52
|
+
- test/max_heap_test.rb
|
52
53
|
- test/multi_dimensional_array_test.rb
|
53
54
|
- test/queue_as_array_test.rb
|
54
55
|
- test/singly_linked_list_element_test.rb
|
@@ -64,27 +65,23 @@ rdoc_options: []
|
|
64
65
|
require_paths:
|
65
66
|
- lib
|
66
67
|
required_ruby_version: !ruby/object:Gem::Requirement
|
67
|
-
none: false
|
68
68
|
requirements:
|
69
69
|
- - ">="
|
70
70
|
- !ruby/object:Gem::Version
|
71
|
-
hash: 3
|
72
71
|
segments:
|
73
72
|
- 0
|
74
73
|
version: "0"
|
75
74
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
76
|
-
none: false
|
77
75
|
requirements:
|
78
76
|
- - ">="
|
79
77
|
- !ruby/object:Gem::Version
|
80
|
-
hash: 3
|
81
78
|
segments:
|
82
79
|
- 0
|
83
80
|
version: "0"
|
84
81
|
requirements: []
|
85
82
|
|
86
83
|
rubyforge_project: RubyDataStructures
|
87
|
-
rubygems_version: 1.3.
|
84
|
+
rubygems_version: 1.3.6
|
88
85
|
signing_key:
|
89
86
|
specification_version: 3
|
90
87
|
summary: Implementation of standard data structures in Ruby
|
data/README
DELETED