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
@@ -1,24 +0,0 @@
|
|
1
|
-
module DS
|
2
|
-
class GraphAsTriMatrix < GraphAsMatrix
|
3
|
-
|
4
|
-
def initialize(edges)
|
5
|
-
@store = TriMatrix.new(0)
|
6
|
-
@max = 0
|
7
|
-
@map = OrderedSet.new
|
8
|
-
|
9
|
-
add_edges(edges)
|
10
|
-
end
|
11
|
-
|
12
|
-
#Returns vertex degree.
|
13
|
-
def degree(x)
|
14
|
-
x = @map.index(x)
|
15
|
-
sum = 0
|
16
|
-
0.upto @max do |i|
|
17
|
-
sum += @store[x,i] if @store[x,i]
|
18
|
-
end
|
19
|
-
sum
|
20
|
-
end
|
21
|
-
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
data/lib/ds/lists/cyclic_list.rb
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
module DS
|
2
|
-
|
3
|
-
#Class represent list with cycle.
|
4
|
-
class CyclicList < List
|
5
|
-
|
6
|
-
#Returns cycle size. If list has no cycles returns 0.
|
7
|
-
def cycle_size
|
8
|
-
counter = 0
|
9
|
-
if start = self.joint
|
10
|
-
counter = 1
|
11
|
-
elem = joint.next
|
12
|
-
while elem != start
|
13
|
-
elem = elem.next
|
14
|
-
counter += 1
|
15
|
-
end
|
16
|
-
end
|
17
|
-
counter
|
18
|
-
end
|
19
|
-
|
20
|
-
end
|
21
|
-
end
|
data/lib/ds/lists/ring.rb
DELETED
@@ -1,42 +0,0 @@
|
|
1
|
-
module DS
|
2
|
-
|
3
|
-
#Ring - represent list which head is linked with tail.
|
4
|
-
class Ring < CyclicList
|
5
|
-
|
6
|
-
#Creates ring from array.
|
7
|
-
def self.from_array(arr)
|
8
|
-
list = Ring.new(arr.shift)
|
9
|
-
tail = list.head
|
10
|
-
arr.each { |e| tail = tail.append(e) }
|
11
|
-
tail.next = list.head
|
12
|
-
list
|
13
|
-
end
|
14
|
-
|
15
|
-
def length
|
16
|
-
cycle_size
|
17
|
-
end
|
18
|
-
|
19
|
-
#Removes ring elements by k until there is only one element in list.
|
20
|
-
def eliminate_by(k)
|
21
|
-
elem = self.head
|
22
|
-
prev = elem
|
23
|
-
|
24
|
-
k = k-1
|
25
|
-
|
26
|
-
while prev != elem.next
|
27
|
-
|
28
|
-
k.times do
|
29
|
-
prev = elem
|
30
|
-
elem = elem.next
|
31
|
-
end
|
32
|
-
|
33
|
-
prev.next = elem.next
|
34
|
-
elem = prev.next
|
35
|
-
end
|
36
|
-
|
37
|
-
return prev.data
|
38
|
-
|
39
|
-
end
|
40
|
-
|
41
|
-
end
|
42
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
module DS
|
2
|
-
|
3
|
-
#Class provides access to any element in array. If index i
|
4
|
-
#is greter than array size then elements from size to i are
|
5
|
-
#filled with extender.
|
6
|
-
class ExpandableArray < Array
|
7
|
-
def initialize(size=0,extender=0)
|
8
|
-
@extender = extender
|
9
|
-
super(size,extender)
|
10
|
-
end
|
11
|
-
|
12
|
-
#Returns element at index. If index is greater than size of array then
|
13
|
-
#elements from size to index are filled with extender.
|
14
|
-
def [](x)
|
15
|
-
if x >=size
|
16
|
-
for i in size..x
|
17
|
-
self[i]=@extender
|
18
|
-
end
|
19
|
-
end
|
20
|
-
super(x)
|
21
|
-
end
|
22
|
-
|
23
|
-
#Sets the element at index. If index is greater than size of array then
|
24
|
-
#elements from size to index are filled with extender.
|
25
|
-
def []=(x,v)
|
26
|
-
max = size
|
27
|
-
super(x,v)
|
28
|
-
if size - max >1
|
29
|
-
(max..size-2).each do |i|
|
30
|
-
self[i] = @extender
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
|
@@ -1,30 +0,0 @@
|
|
1
|
-
module DS
|
2
|
-
class TriMatrix
|
3
|
-
|
4
|
-
#Class implements Triangular Matrix (lower).
|
5
|
-
|
6
|
-
#Creates new triangular matrix.
|
7
|
-
def initialize(init=0)
|
8
|
-
@store =ExpandableArray.new(0,init)
|
9
|
-
end
|
10
|
-
|
11
|
-
#Returns element at index x,y (or y,x).
|
12
|
-
def [](x,y)
|
13
|
-
x,y = y,x if y > x
|
14
|
-
index = (x*x+x)/2 +y
|
15
|
-
@store[index]
|
16
|
-
end
|
17
|
-
|
18
|
-
#Sets the element at index x,y (or y,x).
|
19
|
-
def []=(x,y,v)
|
20
|
-
x,y = y,x if y>x
|
21
|
-
index = (x*x+x)/2 +y
|
22
|
-
@store[index] = v
|
23
|
-
end
|
24
|
-
|
25
|
-
def to_a
|
26
|
-
@store
|
27
|
-
end
|
28
|
-
|
29
|
-
end
|
30
|
-
end
|
data/lib/ds/queues/queue.rb
DELETED
@@ -1,53 +0,0 @@
|
|
1
|
-
module DS
|
2
|
-
|
3
|
-
#Class implements queue data structure.
|
4
|
-
|
5
|
-
class Queue
|
6
|
-
|
7
|
-
#Create new queue. First parameter determines how the queue will be represented internally.
|
8
|
-
def initialize(store = :array)
|
9
|
-
if store == :array
|
10
|
-
@store = []
|
11
|
-
else
|
12
|
-
@store = List.new
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
#Create new queue. Internaly uses list to store elements.
|
17
|
-
def Queue.create
|
18
|
-
new(:list)
|
19
|
-
end
|
20
|
-
|
21
|
-
#Adds element to queue and returns queue itself.
|
22
|
-
def enqueue(x)
|
23
|
-
@store << x
|
24
|
-
self
|
25
|
-
end
|
26
|
-
|
27
|
-
alias :push :enqueue
|
28
|
-
|
29
|
-
#Removes element from queue and returns it.
|
30
|
-
def dequeue
|
31
|
-
@store.shift
|
32
|
-
end
|
33
|
-
|
34
|
-
alias :shift :dequeue
|
35
|
-
|
36
|
-
#Returns element from forehead of queue.
|
37
|
-
def peek
|
38
|
-
@store.first
|
39
|
-
end
|
40
|
-
|
41
|
-
#Returns length of queue. If queue is empty returns 0.
|
42
|
-
def length
|
43
|
-
@store.length
|
44
|
-
end
|
45
|
-
|
46
|
-
#Checks if queue is empty.
|
47
|
-
def empty?
|
48
|
-
@store.empty?
|
49
|
-
end
|
50
|
-
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
data/lib/ds/sets/ordered_set.rb
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
module DS
|
2
|
-
class OrderedSet
|
3
|
-
attr_reader :size
|
4
|
-
|
5
|
-
#Creates new Ordered Set.
|
6
|
-
def initialize
|
7
|
-
@size = 0
|
8
|
-
@store = {}
|
9
|
-
end
|
10
|
-
|
11
|
-
#Adds new element to set
|
12
|
-
def push e
|
13
|
-
if index = @store[e]
|
14
|
-
index
|
15
|
-
else
|
16
|
-
@size = @size+1
|
17
|
-
@store[e] = @size-1
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
#Returns element index.
|
22
|
-
def index e
|
23
|
-
@store[e]
|
24
|
-
end
|
25
|
-
|
26
|
-
def to_a
|
27
|
-
@store.sort{|a,b| a[1]<=>b[1]}.map{|e| e.first}
|
28
|
-
end
|
29
|
-
|
30
|
-
|
31
|
-
end
|
32
|
-
end
|
@@ -1,34 +0,0 @@
|
|
1
|
-
module DS
|
2
|
-
class BinarySearchTree < BinaryTree
|
3
|
-
|
4
|
-
#Creates new search tree from array.
|
5
|
-
def self.from_array(arr)
|
6
|
-
tree = BinarySearchTree.new(arr.shift)
|
7
|
-
arr.each do |e|
|
8
|
-
tree.insert e
|
9
|
-
end
|
10
|
-
tree
|
11
|
-
end
|
12
|
-
|
13
|
-
#Inserts new element.
|
14
|
-
def insert x
|
15
|
-
if x > @data and right.nil?
|
16
|
-
self.right = BinarySearchTree.new(x)
|
17
|
-
elsif x <= @data and left.nil?
|
18
|
-
self.left = BinarySearchTree.new(x)
|
19
|
-
elsif x > @data
|
20
|
-
right.insert x
|
21
|
-
else
|
22
|
-
left.insert x
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
#Checks if tree is valid Binary Search Tree.
|
27
|
-
def BinarySearchTree.valid?(other)
|
28
|
-
walker = TreeWalker.new(other)
|
29
|
-
walker.traverse(:inorder)
|
30
|
-
walker.visited.extend(ArrayX).sorted?
|
31
|
-
end
|
32
|
-
|
33
|
-
end
|
34
|
-
end
|
@@ -1,60 +0,0 @@
|
|
1
|
-
module DS
|
2
|
-
class CompleteBinaryTree
|
3
|
-
|
4
|
-
#Creates new tree (stored in array).
|
5
|
-
def initialize(*args)
|
6
|
-
if args.empty?
|
7
|
-
@data = []
|
8
|
-
else
|
9
|
-
@data = args.to_a
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
#Inserts new element.
|
14
|
-
def << (value)
|
15
|
-
@data.push value
|
16
|
-
end
|
17
|
-
|
18
|
-
#Returns root element.
|
19
|
-
def root
|
20
|
-
@data.first
|
21
|
-
end
|
22
|
-
|
23
|
-
#Returns index of left child.
|
24
|
-
def left_index(i)
|
25
|
-
2*i+1
|
26
|
-
end
|
27
|
-
|
28
|
-
#Returns index of right child.
|
29
|
-
def right_index(i)
|
30
|
-
2*i+2
|
31
|
-
end
|
32
|
-
|
33
|
-
#Returns index of parent.
|
34
|
-
def parent_index(i)
|
35
|
-
(i+1)/2 - 1
|
36
|
-
end
|
37
|
-
|
38
|
-
#Returns children of node i.
|
39
|
-
def children(i)
|
40
|
-
[@data[left_index(i)], @data[right_index(i)]]
|
41
|
-
end
|
42
|
-
|
43
|
-
#Returns left child of node i.
|
44
|
-
def left(i)
|
45
|
-
@data[left_index(i)]
|
46
|
-
end
|
47
|
-
|
48
|
-
#Returns left child of node i.
|
49
|
-
def right(i)
|
50
|
-
@data[right_index(i)]
|
51
|
-
end
|
52
|
-
|
53
|
-
#Returns parent of node i.
|
54
|
-
def parent(i)
|
55
|
-
@data[parent_index(i)]
|
56
|
-
end
|
57
|
-
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
data/test/test_array_x.rb
DELETED
@@ -1,51 +0,0 @@
|
|
1
|
-
require 'help'
|
2
|
-
|
3
|
-
describe ArrayX do
|
4
|
-
|
5
|
-
before do
|
6
|
-
@asc = [1,3,6,9,10,13].extend(ArrayX)
|
7
|
-
@desc = [9,8,7,7,4,3,2].extend(ArrayX)
|
8
|
-
@short = [1,2].extend(ArrayX)
|
9
|
-
|
10
|
-
@empty = [].extend(ArrayX)
|
11
|
-
@one = [3].extend(ArrayX)
|
12
|
-
@not_sorted = [3,4,9,1,1,2,8].extend(ArrayX)
|
13
|
-
end
|
14
|
-
|
15
|
-
it "#sorted? should check if array is already sorted." do
|
16
|
-
assert @desc.sorted?
|
17
|
-
assert @asc.sorted?
|
18
|
-
assert @empty.sorted?
|
19
|
-
assert @one.sorted?
|
20
|
-
assert @short.sorted?
|
21
|
-
refute @not_sorted.sorted?
|
22
|
-
assert @desc.sorted?(:desc)
|
23
|
-
refute @desc.sorted?(:asc)
|
24
|
-
assert @asc.sorted?(:asc)
|
25
|
-
refute @asc.sorted?(:desc)
|
26
|
-
refute @not_sorted.sorted?(:des)
|
27
|
-
refute @not_sorted.sorted?(:asc)
|
28
|
-
assert @short.sorted?(:asc)
|
29
|
-
refute @short.sorted?(:desc)
|
30
|
-
|
31
|
-
assert @one.sorted?(:asc)
|
32
|
-
assert @one.sorted?(:asc)
|
33
|
-
|
34
|
-
end
|
35
|
-
|
36
|
-
it "#duplications? should check if array has duplicates." do
|
37
|
-
refute @asc.duplications?
|
38
|
-
assert @desc.duplications?
|
39
|
-
assert @not_sorted.duplications?
|
40
|
-
refute @empty.duplications?
|
41
|
-
end
|
42
|
-
|
43
|
-
it "#tail should return array without first element." do
|
44
|
-
@asc.tail.must_equal [3,6,9,10,13]
|
45
|
-
@short.tail.must_equal [2]
|
46
|
-
@one.tail.must_equal []
|
47
|
-
@empty.tail.must_be_nil
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
|
@@ -1,39 +0,0 @@
|
|
1
|
-
require 'help'
|
2
|
-
|
3
|
-
describe BinarySearchTree do
|
4
|
-
|
5
|
-
before do
|
6
|
-
|
7
|
-
|
8
|
-
t = BinarySearchTree.new(7)
|
9
|
-
c1 = t.insert 5
|
10
|
-
c2 = t.insert 8
|
11
|
-
|
12
|
-
c3 = c1.insert 2
|
13
|
-
c1.insert 6
|
14
|
-
|
15
|
-
c3.insert 1
|
16
|
-
|
17
|
-
@bst = t
|
18
|
-
|
19
|
-
@bin_tree = BinaryTree.new
|
20
|
-
[2,5,8,9,11,12,14].each{|x| @bin_tree.insert(x)}
|
21
|
-
|
22
|
-
end
|
23
|
-
|
24
|
-
it "should be valid Binary Search Tree." do
|
25
|
-
assert BinarySearchTree.valid?(@bst)
|
26
|
-
end
|
27
|
-
|
28
|
-
it "#from_array should create new valid BinarySearchTree." do
|
29
|
-
b = BinarySearchTree.from_array([8,1,5,2,7,6,3])
|
30
|
-
assert BinarySearchTree.valid?(b)
|
31
|
-
TreeWalker.new(b).traverse(:inorder).must_equal [1,2,3,5,6,7,8]
|
32
|
-
end
|
33
|
-
|
34
|
-
it "not every Binary Tree is valid Binary Search Tree." do
|
35
|
-
refute BinarySearchTree.valid?(@bin_tree)
|
36
|
-
end
|
37
|
-
|
38
|
-
end
|
39
|
-
|
@@ -1,58 +0,0 @@
|
|
1
|
-
require 'help'
|
2
|
-
|
3
|
-
describe CompleteBinaryTree do
|
4
|
-
|
5
|
-
before do
|
6
|
-
@tree = CompleteBinaryTree.new(1,2,3,4,5,6,7)
|
7
|
-
@empty_tree = CompleteBinaryTree.new
|
8
|
-
end
|
9
|
-
|
10
|
-
it "#<< should add new element." do
|
11
|
-
@empty_tree << 1
|
12
|
-
@empty_tree << 2
|
13
|
-
@empty_tree.root.must_equal 1
|
14
|
-
end
|
15
|
-
|
16
|
-
it "#root should return root of the tree." do
|
17
|
-
@tree.root.must_equal 1
|
18
|
-
end
|
19
|
-
|
20
|
-
it "#left_index should return index of left child" do
|
21
|
-
@tree.left_index(0).must_equal 1
|
22
|
-
@tree.left_index(1).must_equal 3
|
23
|
-
end
|
24
|
-
|
25
|
-
it "#right_index should return index of left child" do
|
26
|
-
@tree.right_index(0).must_equal 2
|
27
|
-
@tree.right_index(1).must_equal 4
|
28
|
-
end
|
29
|
-
|
30
|
-
it "#parent_index should return index of left child" do
|
31
|
-
@tree.parent_index(1).must_equal 0
|
32
|
-
@tree.parent_index(3).must_equal 1
|
33
|
-
end
|
34
|
-
|
35
|
-
it "#left should return left child" do
|
36
|
-
@tree.left(0).must_equal 2
|
37
|
-
@tree.left(1).must_equal 4
|
38
|
-
end
|
39
|
-
|
40
|
-
it "#right should return right child" do
|
41
|
-
@tree.right(0).must_equal 3
|
42
|
-
@tree.right(1).must_equal 5
|
43
|
-
end
|
44
|
-
|
45
|
-
it "#parent should return parent." do
|
46
|
-
@tree.parent(3).must_equal 2
|
47
|
-
@tree.parent(4).must_equal 2
|
48
|
-
@tree.parent(1).must_equal 1
|
49
|
-
end
|
50
|
-
|
51
|
-
it "#children should return children." do
|
52
|
-
@tree.children(0).must_equal [2,3]
|
53
|
-
end
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
end
|
58
|
-
|