DSA 0.0.1 → 0.0.2
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 +4 -4
- data/README.md +128 -127
- data/lib/DSA/algorithm.rb +4 -5
- data/lib/DSA/version.rb +1 -1
- data/test/algorithms_test.rb +17 -8
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8b389b9d9e679bc3e426a95abfc2f103c93596a8
|
4
|
+
data.tar.gz: d44481bab4cc8cf982623829d822f91193880f3e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 284aba1b513d954e3a87033ae58b3c4bb9b3123f9f1c49e028e310e0c2f36a6f79d9c5468f17564808e75fa83cc9c0a7736a0623128b3e863d1c49c671614312
|
7
|
+
data.tar.gz: ff67a7432ac7656b1a7697f11448c1148fcc1034c4d5dcc4107a4f560abf33529354149c19aafa6289d8115d8c802146b5f5f47b85ab4cbecaadc22746d1092c
|
data/README.md
CHANGED
@@ -1,127 +1,128 @@
|
|
1
|
-
# DSA
|
2
|
-
|
3
|
-
Ruby gem for basic Data Structures and Algorithms
|
4
|
-
|
5
|
-
## Installation
|
6
|
-
|
7
|
-
Add this line to your application's Gemfile:
|
8
|
-
|
9
|
-
gem 'DSA'
|
10
|
-
|
11
|
-
And then execute:
|
12
|
-
|
13
|
-
$ bundle
|
14
|
-
|
15
|
-
Or install it yourself as:
|
16
|
-
|
17
|
-
$ gem install DSA
|
18
|
-
|
19
|
-
## Usage
|
20
|
-
|
21
|
-
To include the package,
|
22
|
-
|
23
|
-
require 'DSA'
|
24
|
-
|
25
|
-
|
26
|
-
### List
|
27
|
-
A doubly linked list data structure. Use when there are lots of insertions/deletions in the middle,
|
28
|
-
otherwise, built-in array is better.
|
29
|
-
|
30
|
-
l = DSA::List.new
|
31
|
-
l.push 'some value'
|
32
|
-
l.pop
|
33
|
-
l.unshift 'some value'
|
34
|
-
l.shift
|
35
|
-
l.first
|
36
|
-
l.last
|
37
|
-
l.empty?
|
38
|
-
l.length
|
39
|
-
|
40
|
-
General access/removal/insertion using index is supported, these operations require linear time, so use carefully.
|
41
|
-
|
42
|
-
l[2]
|
43
|
-
l.insert_at 10, 'some value'
|
44
|
-
l.remove_at 2
|
45
|
-
|
46
|
-
To do lots of insertions/deletions, use the iterator, StopIteration is raised when reaching to head or tail
|
47
|
-
|
48
|
-
li = l.begin_iterator # the iterator starts from the head
|
49
|
-
puts li.next
|
50
|
-
li.insert 'some value'
|
51
|
-
li.remove
|
52
|
-
li.update 'new value'
|
53
|
-
|
54
|
-
li = l.end_iterator # the iterator starts from the tail
|
55
|
-
li.previous
|
56
|
-
|
57
|
-
Enumerable is included, all those method such as 'each' are all available, since other methods are based on each,
|
58
|
-
the performance might not be the best, use only when a full traversal is inevitable.
|
59
|
-
|
60
|
-
### BinarySearchTree
|
61
|
-
An ordered map, works like a hash, but preserves an order and provides range search, implemented as a RedBlack tree.
|
62
|
-
|
63
|
-
The following three are aliases in creating a new object,
|
64
|
-
|
65
|
-
rb = DSA::BinarySearchTree.new
|
66
|
-
rb = DSA::OrderedMap.new
|
67
|
-
rb = DSA::RedBlackTree.new
|
68
|
-
|
69
|
-
Method are very like a hash,
|
70
|
-
|
71
|
-
rb[key] = value
|
72
|
-
rb[key]
|
73
|
-
rb.delete key
|
74
|
-
|
75
|
-
And special methods related to orders, those methods yield key/value pairs to block, if no block, enumerator is returned.
|
76
|
-
|
77
|
-
rb.each # in-order traversal
|
78
|
-
rb.gt(key) # key/value pairs for keys greater than key
|
79
|
-
rb.ge(key)
|
80
|
-
rb.lt(key)
|
81
|
-
rb.le(key)
|
82
|
-
|
83
|
-
A help method tried to print a tree, not quite pretty, but may helps test
|
84
|
-
|
85
|
-
rb.bfs_print
|
86
|
-
|
87
|
-
Enumerable is included, all those method such as 'each' are all available, since other methods are based on each,
|
88
|
-
the performance might not be the best, use only when a full traversal is inevitable.
|
89
|
-
|
90
|
-
|
91
|
-
### PriorityQueue
|
92
|
-
An array based heap, priority is a number, the smaller it is, higher priority it has
|
93
|
-
|
94
|
-
pq = DSA::PriorityQueue.new
|
95
|
-
pq.add 10, 'some job'
|
96
|
-
pq.length
|
97
|
-
pq.top # look at the highest priority without removing it
|
98
|
-
job = pq.pop # get and remove the highest priority job
|
99
|
-
|
100
|
-
|
101
|
-
### Stack and Queue
|
102
|
-
Implemented based on array or list.
|
103
|
-
|
104
|
-
s = DSA::ArrayStack.new
|
105
|
-
s = DSA::ListStack.new
|
106
|
-
s.push 'some value'
|
107
|
-
s.pop
|
108
|
-
s.empty?
|
109
|
-
s.top
|
110
|
-
s.length
|
111
|
-
|
112
|
-
q = DSA::ArrayQueue.new
|
113
|
-
q = DSA::ListQueue.new
|
114
|
-
q.enqueue 'some value'
|
115
|
-
q.dequeue
|
116
|
-
q.empty?
|
117
|
-
q.first
|
118
|
-
q.length
|
119
|
-
|
120
|
-
### Algorithm
|
121
|
-
The following functions are for demonstrations, specially sort, using built-in Array#bsearch and Array#sort instead,
|
122
|
-
they have a better performance.
|
123
|
-
|
124
|
-
DSA::Algorithm::factorial(5)
|
125
|
-
DSA::Algorithm::binary_search((1..9).to_a, 2, 0, 8)
|
126
|
-
DSA::Algorithm::insertion_sort!(array)
|
127
|
-
DSA::Algorithm::quick_sort!(array, 0, array.length-1)
|
1
|
+
# DSA
|
2
|
+
|
3
|
+
Ruby gem for basic Data Structures and Algorithms
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
```bash
|
9
|
+
gem 'DSA'
|
10
|
+
```
|
11
|
+
And then execute:
|
12
|
+
```bash
|
13
|
+
$ bundle
|
14
|
+
```
|
15
|
+
Or install it yourself as:
|
16
|
+
```bash
|
17
|
+
$ gem install DSA
|
18
|
+
```
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
To include the package,
|
22
|
+
```ruby
|
23
|
+
require 'DSA'
|
24
|
+
```
|
25
|
+
|
26
|
+
### List
|
27
|
+
A doubly linked list data structure. Use when there are lots of insertions/deletions in the middle,
|
28
|
+
otherwise, built-in array is better.
|
29
|
+
```ruby
|
30
|
+
l = DSA::List.new
|
31
|
+
l.push 'some value'
|
32
|
+
l.pop
|
33
|
+
l.unshift 'some value'
|
34
|
+
l.shift
|
35
|
+
l.first
|
36
|
+
l.last
|
37
|
+
l.empty?
|
38
|
+
l.length
|
39
|
+
```
|
40
|
+
General access/removal/insertion using index is supported, these operations require linear time, so use carefully.
|
41
|
+
```ruby
|
42
|
+
l[2]
|
43
|
+
l.insert_at 10, 'some value'
|
44
|
+
l.remove_at 2
|
45
|
+
```
|
46
|
+
To do lots of insertions/deletions, use the iterator, StopIteration is raised when reaching to head or tail
|
47
|
+
```ruby
|
48
|
+
li = l.begin_iterator # the iterator starts from the head
|
49
|
+
puts li.next
|
50
|
+
li.insert 'some value'
|
51
|
+
li.remove
|
52
|
+
li.update 'new value'
|
53
|
+
|
54
|
+
li = l.end_iterator # the iterator starts from the tail
|
55
|
+
li.previous
|
56
|
+
```
|
57
|
+
Enumerable is included, all those method such as 'each' are all available, since other methods are based on each,
|
58
|
+
the performance might not be the best, use only when a full traversal is inevitable.
|
59
|
+
|
60
|
+
### BinarySearchTree
|
61
|
+
An ordered map, works like a hash, but preserves an order and provides range search, implemented as a RedBlack tree.
|
62
|
+
|
63
|
+
The following three are aliases in creating a new object,
|
64
|
+
```ruby
|
65
|
+
rb = DSA::BinarySearchTree.new
|
66
|
+
rb = DSA::OrderedMap.new
|
67
|
+
rb = DSA::RedBlackTree.new
|
68
|
+
```
|
69
|
+
Method are very like a hash,
|
70
|
+
```ruby
|
71
|
+
rb[key] = value
|
72
|
+
rb[key]
|
73
|
+
rb.delete key
|
74
|
+
```
|
75
|
+
And special methods related to orders, those methods yield key/value pairs to block, if no block, enumerator is returned.
|
76
|
+
```ruby
|
77
|
+
rb.each # in-order traversal
|
78
|
+
rb.gt(key) # key/value pairs for keys greater than key
|
79
|
+
rb.ge(key)
|
80
|
+
rb.lt(key)
|
81
|
+
rb.le(key)
|
82
|
+
```
|
83
|
+
A help method tried to print a tree, not quite pretty, but may helps test
|
84
|
+
```ruby
|
85
|
+
rb.bfs_print
|
86
|
+
```
|
87
|
+
Enumerable is included, all those method such as 'each' are all available, since other methods are based on each,
|
88
|
+
the performance might not be the best, use only when a full traversal is inevitable.
|
89
|
+
|
90
|
+
|
91
|
+
### PriorityQueue
|
92
|
+
An array based heap, priority is a number, the smaller it is, higher priority it has
|
93
|
+
```ruby
|
94
|
+
pq = DSA::PriorityQueue.new
|
95
|
+
pq.add 10, 'some job'
|
96
|
+
pq.length
|
97
|
+
pq.top # look at the highest priority without removing it
|
98
|
+
job = pq.pop # get and remove the highest priority job
|
99
|
+
```
|
100
|
+
|
101
|
+
### Stack and Queue
|
102
|
+
Implemented based on array or list.
|
103
|
+
```ruby
|
104
|
+
s = DSA::ArrayStack.new
|
105
|
+
s = DSA::ListStack.new
|
106
|
+
s.push 'some value'
|
107
|
+
s.pop
|
108
|
+
s.empty?
|
109
|
+
s.top
|
110
|
+
s.length
|
111
|
+
|
112
|
+
q = DSA::ArrayQueue.new
|
113
|
+
q = DSA::ListQueue.new
|
114
|
+
q.enqueue 'some value'
|
115
|
+
q.dequeue
|
116
|
+
q.empty?
|
117
|
+
q.first
|
118
|
+
q.length
|
119
|
+
```
|
120
|
+
### Algorithm
|
121
|
+
The following functions are for demonstrations, specially sort, using built-in Array#bsearch and Array#sort instead,
|
122
|
+
they have a better performance.
|
123
|
+
```ruby
|
124
|
+
DSA::Algorithm::factorial(5)
|
125
|
+
DSA::Algorithm::binary_search((1..9).to_a, 2, 0, 8)
|
126
|
+
DSA::Algorithm::insertion_sort!(array)
|
127
|
+
DSA::Algorithm::quick_sort!(array, 0, array.length-1)
|
128
|
+
```
|
data/lib/DSA/algorithm.rb
CHANGED
@@ -44,9 +44,9 @@ module DSA
|
|
44
44
|
# in place quick sort
|
45
45
|
def self.quick_sort!(data, low, high)
|
46
46
|
return if low >= high
|
47
|
-
pivot = data[high]
|
47
|
+
pivot = data[Random.rand(low..high)]
|
48
48
|
left = low
|
49
|
-
right = high
|
49
|
+
right = high
|
50
50
|
while left <= right
|
51
51
|
until left > right || data[left] >= pivot
|
52
52
|
left += 1
|
@@ -60,9 +60,8 @@ module DSA
|
|
60
60
|
right -= 1
|
61
61
|
end
|
62
62
|
end
|
63
|
-
data
|
64
|
-
quick_sort!(data,
|
65
|
-
quick_sort!(data, left+1, high)
|
63
|
+
quick_sort!(data, low, right)
|
64
|
+
quick_sort!(data, left, high)
|
66
65
|
end
|
67
66
|
|
68
67
|
end
|
data/lib/DSA/version.rb
CHANGED
data/test/algorithms_test.rb
CHANGED
@@ -47,32 +47,41 @@ class MyTest < Test::Unit::TestCase
|
|
47
47
|
DSA::Algorithm::quick_sort!(original, 0, original.length-1)
|
48
48
|
assert_equal expect, original, 'sort failed'
|
49
49
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
sorted_b = (0..value).to_a
|
55
|
-
sorted_c = (0..value).to_a
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_sort_performance
|
53
|
+
|
56
54
|
|
57
55
|
|
58
56
|
puts 'sort on already sorted'
|
57
|
+
puts
|
58
|
+
value = 10**5
|
59
|
+
sorted_a = (0..value).to_a
|
60
|
+
sorted_b = sorted_a.map {|e| e}
|
61
|
+
sorted_c = sorted_a.map {|e| e}
|
62
|
+
assert_equal sorted_a, sorted_b, ''
|
63
|
+
assert_equal sorted_a, sorted_c, ''
|
59
64
|
Benchmark.bm(20) do |x|
|
60
65
|
x.report('insertion sort') { DSA::Algorithm::insertion_sort! sorted_a }
|
61
66
|
x.report('quick sort') { DSA::Algorithm::quick_sort! sorted_c, 0, sorted_c.length-1 }
|
62
67
|
x.report('built in sort') { sorted_b.sort! }
|
63
68
|
end
|
69
|
+
assert_equal sorted_a, sorted_b, ''
|
70
|
+
assert_equal sorted_a, sorted_c, ''
|
64
71
|
|
65
72
|
|
66
73
|
puts 'sort on not sorted'
|
67
74
|
value = 10**4
|
68
75
|
not_sorted_a = value.times.map { Random.rand(value) }
|
69
|
-
not_sorted_b =
|
70
|
-
not_sorted_c =
|
76
|
+
not_sorted_b = not_sorted_a.map { |e| e }
|
77
|
+
not_sorted_c = not_sorted_a.map { |e| e }
|
71
78
|
Benchmark.bm(20) do |x|
|
72
79
|
x.report('insertion sort') { DSA::Algorithm::insertion_sort! not_sorted_a }
|
73
80
|
x.report('quick sort') { DSA::Algorithm::quick_sort! not_sorted_c, 0, not_sorted_c.length-1 }
|
74
81
|
x.report('built in sort') { not_sorted_b.sort! }
|
75
82
|
end
|
83
|
+
assert_equal not_sorted_a, not_sorted_b, ''
|
84
|
+
assert_equal not_sorted_a, not_sorted_c, ''
|
76
85
|
|
77
86
|
puts 'sort on not sorted'
|
78
87
|
value = 10**6
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: DSA
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- lusaisai
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-03-
|
11
|
+
date: 2014-03-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|