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
@@ -1,26 +1,29 @@
|
|
1
|
-
module DS
|
2
|
-
|
3
|
-
#Container for linked lists elements.
|
1
|
+
module DS
|
2
|
+
# Container for linked lists elements.
|
4
3
|
class ListElement
|
4
|
+
attr_accessor :data, :next, :prev
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
def initialize(x=nil)
|
6
|
+
def initialize(x = nil)
|
9
7
|
@data = x
|
10
|
-
@next= nil
|
8
|
+
@next = nil
|
9
|
+
@prev = nil
|
11
10
|
end
|
12
|
-
|
13
|
-
#Adds new element to list.
|
11
|
+
|
12
|
+
# Adds new element to list.
|
14
13
|
def append(x)
|
15
14
|
elem = ListElement.new(x)
|
15
|
+
elem.prev = self
|
16
16
|
self.next = elem
|
17
17
|
end
|
18
18
|
|
19
|
-
#Checks if given element is last.
|
19
|
+
# Checks if given element is last.
|
20
20
|
def tail?
|
21
21
|
@next.nil?
|
22
22
|
end
|
23
23
|
|
24
|
+
# Checks if given element is first.
|
25
|
+
def head?
|
26
|
+
@prev.nil?
|
27
|
+
end
|
24
28
|
end
|
25
29
|
end
|
26
|
-
|
data/lib/ds/pair.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
module DS
|
2
|
+
# Simple class for key, value objects
|
2
3
|
class Pair
|
3
4
|
attr_accessor :key, :value
|
4
5
|
|
5
|
-
alias
|
6
|
-
alias
|
6
|
+
alias first key
|
7
|
+
alias second value
|
7
8
|
|
8
|
-
def initialize(x,y)
|
9
|
+
def initialize(x, y)
|
9
10
|
@key = x
|
10
11
|
@value = y
|
11
12
|
end
|
12
|
-
|
13
13
|
end
|
14
14
|
end
|
@@ -1,36 +1,49 @@
|
|
1
1
|
module DS
|
2
|
-
|
3
|
-
|
4
|
-
#Create new priority queue. Internaly uses heap to store elements.
|
5
|
-
def initialize
|
6
|
-
@store =
|
2
|
+
# Class implements Priority Queue
|
3
|
+
class PriorityQueue
|
4
|
+
# Create new priority queue. Internaly uses heap to store elements.
|
5
|
+
def initialize(*args)
|
6
|
+
@store = if block_given?
|
7
|
+
BinaryHeap.new(*args) do |parent, child|
|
8
|
+
yield parent.key, child.key
|
9
|
+
end
|
10
|
+
else
|
11
|
+
BinaryHeap.new(*args) { |parent, child| parent.key >= child.key }
|
12
|
+
end
|
7
13
|
end
|
8
14
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
pair = Pair.new(priority,x)
|
15
|
+
# Adds element to queue with given priority.
|
16
|
+
def enqueue(x, priority)
|
17
|
+
pair = Pair.new(priority, x)
|
13
18
|
@store.insert(pair)
|
14
19
|
self
|
15
20
|
end
|
16
|
-
|
17
|
-
alias :push :enqueue
|
18
21
|
|
19
|
-
|
22
|
+
alias push enqueue
|
23
|
+
|
24
|
+
# Removes element with highest priority from queue.
|
20
25
|
def dequeue
|
21
|
-
|
22
|
-
|
23
|
-
else
|
24
|
-
x
|
25
|
-
end
|
26
|
+
x = @store.shift
|
27
|
+
x ? x.value : nil
|
26
28
|
end
|
27
29
|
|
28
|
-
alias
|
30
|
+
alias shift dequeue
|
29
31
|
|
30
|
-
#Returns element with highest priority.
|
32
|
+
# Returns element with highest priority.
|
31
33
|
def peek
|
32
|
-
@store.
|
34
|
+
@store.top.value
|
33
35
|
end
|
34
36
|
|
37
|
+
# Returns length of queue. If queue is empty returns 0.
|
38
|
+
def length
|
39
|
+
@store.length
|
40
|
+
end
|
41
|
+
|
42
|
+
alias size length
|
43
|
+
|
44
|
+
# Checks if queue is empty.
|
45
|
+
def empty?
|
46
|
+
@store.empty?
|
47
|
+
end
|
35
48
|
end
|
36
49
|
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module DS
|
2
|
+
# Class implements queue data structure.
|
3
|
+
class SimpleQueue
|
4
|
+
# Create new queue.
|
5
|
+
# First parameter determines how the queue will be represented internally.
|
6
|
+
def initialize(*args)
|
7
|
+
@store = if args.first.is_a? List
|
8
|
+
args.first
|
9
|
+
else
|
10
|
+
args || []
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# Create new queue. Internaly uses List to store elements.
|
15
|
+
def self.create(*args)
|
16
|
+
new(List.new(*args))
|
17
|
+
end
|
18
|
+
|
19
|
+
# Adds element to queue and returns queue itself.
|
20
|
+
def enqueue(x)
|
21
|
+
store << x
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
alias push enqueue
|
26
|
+
|
27
|
+
# Removes element from queue and returns it.
|
28
|
+
def dequeue
|
29
|
+
store.shift
|
30
|
+
end
|
31
|
+
|
32
|
+
alias shift dequeue
|
33
|
+
|
34
|
+
# Returns element from forehead of queue.
|
35
|
+
def peek
|
36
|
+
store.first
|
37
|
+
end
|
38
|
+
|
39
|
+
# Returns length of queue. If queue is empty returns 0.
|
40
|
+
def length
|
41
|
+
store.length
|
42
|
+
end
|
43
|
+
|
44
|
+
alias size length
|
45
|
+
|
46
|
+
# Checks if queue is empty.
|
47
|
+
def empty?
|
48
|
+
store.empty?
|
49
|
+
end
|
50
|
+
|
51
|
+
protected
|
52
|
+
|
53
|
+
attr_reader :store
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module DS
|
2
|
+
# IndexedSet Class
|
3
|
+
class IndexedSet
|
4
|
+
attr_reader :size
|
5
|
+
|
6
|
+
# Creates new Indexed Set.
|
7
|
+
def initialize
|
8
|
+
@size = 0
|
9
|
+
@store = {}
|
10
|
+
@cache = []
|
11
|
+
end
|
12
|
+
|
13
|
+
# Adds new element to set
|
14
|
+
def push(e)
|
15
|
+
unless @store[e]
|
16
|
+
index = size
|
17
|
+
@store[e] = index
|
18
|
+
@size += 1
|
19
|
+
@cache[index] = e
|
20
|
+
end
|
21
|
+
@store[e]
|
22
|
+
end
|
23
|
+
|
24
|
+
# Returns element index.
|
25
|
+
def index(e)
|
26
|
+
@store[e]
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_a
|
30
|
+
@cache
|
31
|
+
end
|
32
|
+
|
33
|
+
def empty?
|
34
|
+
@size == 0
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/ds/stacks/stack.rb
CHANGED
@@ -1,39 +1,47 @@
|
|
1
1
|
module DS
|
2
|
-
|
3
|
-
#
|
4
|
-
#Internaly uses array to store elements.
|
5
|
-
|
2
|
+
# Class implements Stack data structure.
|
3
|
+
# Internaly uses array or linked list to store elements.
|
6
4
|
class Stack
|
7
|
-
|
8
|
-
|
9
|
-
|
5
|
+
def initialize(*args)
|
6
|
+
@store = if args.first.is_a? List
|
7
|
+
args.first
|
8
|
+
else
|
9
|
+
args || []
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# Creates stack internally implemented as List
|
14
|
+
def self.create(*args)
|
15
|
+
new(List.new(*args))
|
10
16
|
end
|
11
17
|
|
12
|
-
#Returns the stack size.
|
18
|
+
# Returns the stack size.
|
13
19
|
def size
|
14
|
-
|
20
|
+
store.size
|
15
21
|
end
|
16
22
|
|
17
23
|
# Removes element from stack and returns it.
|
18
24
|
def pop
|
19
|
-
|
25
|
+
store.pop unless empty?
|
20
26
|
end
|
21
|
-
|
22
|
-
# Adds element
|
27
|
+
|
28
|
+
# Adds element on the top of the stack.
|
23
29
|
def push(x)
|
24
|
-
|
30
|
+
store.push x
|
25
31
|
end
|
26
32
|
|
27
33
|
# Returns element from the top of the stack.
|
28
34
|
def peek
|
29
|
-
|
35
|
+
store.last
|
30
36
|
end
|
31
37
|
|
32
38
|
# If stack is empty returns true otherwise returns false.
|
33
39
|
def empty?
|
34
|
-
|
40
|
+
store.empty?
|
35
41
|
end
|
36
|
-
end
|
37
|
-
end
|
38
42
|
|
43
|
+
protected
|
39
44
|
|
45
|
+
attr_reader :store
|
46
|
+
end
|
47
|
+
end
|
data/lib/ds/trees/binary_heap.rb
CHANGED
@@ -1,102 +1,107 @@
|
|
1
1
|
module DS
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
#
|
2
|
+
# Create new Heap from args.
|
3
|
+
class BinaryHeap
|
4
|
+
attr_reader :store
|
5
|
+
|
6
|
+
# Create new Heap from args.
|
7
|
+
# Given block sets the heap relation. Default heap relation is Max Heap.
|
7
8
|
def initialize(*args, &block)
|
8
|
-
if block_given?
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
@
|
9
|
+
@relation = if block_given?
|
10
|
+
block
|
11
|
+
else
|
12
|
+
-> (parent, child) { parent >= child }
|
13
|
+
end
|
14
|
+
@store = HeapStore.new(*args)
|
14
15
|
heapify!
|
15
16
|
end
|
16
17
|
|
17
|
-
#Create new Maximum Heap from args.
|
18
|
-
def
|
19
|
-
new(*args){|parent,child| parent >= child}
|
18
|
+
# Create new Maximum Heap from args.
|
19
|
+
def self.max(*args)
|
20
|
+
new(*args) { |parent, child| parent >= child }
|
20
21
|
end
|
21
22
|
|
22
|
-
#Create new Minimum Heap from args.
|
23
|
-
def
|
24
|
-
new(*args){|parent,child| parent < child}
|
23
|
+
# Create new Minimum Heap from args.
|
24
|
+
def self.min(*args)
|
25
|
+
new(*args) { |parent, child| parent < child }
|
25
26
|
end
|
26
27
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
@relation.call(@data[parent],@data[child])
|
28
|
+
# Evaluates Heap relation.
|
29
|
+
def relation(parent, child)
|
30
|
+
@relation.call(store[parent], store[child])
|
31
31
|
end
|
32
32
|
|
33
|
-
#Arranges data in heap.
|
34
|
-
#O(n)
|
33
|
+
# Arranges data in heap.
|
34
|
+
# O(n)
|
35
35
|
def heapify!
|
36
|
-
(
|
37
|
-
heapify(i)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
#Maintains heap condition for i node.
|
42
|
-
#O(log)
|
43
|
-
def heapify(i)
|
44
|
-
left = left_index(i)
|
45
|
-
left = nil if left >= @data.size
|
46
|
-
|
47
|
-
right = right_index(i)
|
48
|
-
right = nil if right >= @data.size
|
49
|
-
|
50
|
-
largest = [i,left,right].compact.sort{|x,y| relation(x,y)?-1:1}.first
|
51
|
-
|
52
|
-
if largest != i
|
53
|
-
@data[i], @data[largest] = @data[largest], @data[i]
|
54
|
-
heapify(largest)
|
55
|
-
end
|
36
|
+
(length / 2).downto(1) { |i| sink(i) }
|
56
37
|
end
|
57
38
|
|
58
|
-
#Removes element from heap maintaining heap relation.
|
39
|
+
# Removes element from heap maintaining heap relation.
|
59
40
|
def shift
|
60
|
-
|
61
|
-
result =
|
62
|
-
|
63
|
-
|
64
|
-
|
41
|
+
unless empty?
|
42
|
+
result = store.first
|
43
|
+
swap(1, length)
|
44
|
+
store.pop
|
45
|
+
sink(1)
|
65
46
|
end
|
66
47
|
result
|
67
48
|
end
|
68
49
|
|
69
|
-
#Inserts new value to heap maintaining the heap relation.
|
70
|
-
#Returns heap itself.
|
71
|
-
#O(log)
|
50
|
+
# Inserts new value to heap maintaining the heap relation.
|
51
|
+
# Returns heap itself.
|
52
|
+
# O(log)
|
72
53
|
def insert(value)
|
73
|
-
|
74
|
-
|
75
|
-
parent = parent_index(child)
|
76
|
-
|
77
|
-
while parent >= 0 and !relation(parent,child)
|
78
|
-
@data[child], @data[parent] = @data[parent], @data[child]
|
79
|
-
child = parent
|
80
|
-
parent = parent_index(child)
|
81
|
-
end
|
54
|
+
store.push value
|
55
|
+
swim(length)
|
82
56
|
self
|
83
57
|
end
|
84
58
|
|
85
|
-
|
59
|
+
def top
|
60
|
+
store.first
|
61
|
+
end
|
86
62
|
|
87
63
|
def length
|
88
|
-
|
64
|
+
store.length
|
89
65
|
end
|
90
66
|
|
91
|
-
alias
|
67
|
+
alias size length
|
92
68
|
|
93
69
|
def empty?
|
94
|
-
|
70
|
+
store.empty?
|
95
71
|
end
|
96
72
|
|
97
73
|
def to_a
|
98
|
-
|
74
|
+
store.to_a
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
def swim(k)
|
80
|
+
while k > 1 && less(k / 2, k)
|
81
|
+
swap(k, k / 2)
|
82
|
+
k /= 2
|
83
|
+
end
|
99
84
|
end
|
100
85
|
|
86
|
+
def sink(k)
|
87
|
+
n = length
|
88
|
+
while 2 * k <= n
|
89
|
+
j = 2 * k
|
90
|
+
j += 1 if j < n && less(j, j + 1)
|
91
|
+
break unless less(k, j)
|
92
|
+
swap(k, j)
|
93
|
+
k = j
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def less(x, y)
|
98
|
+
!relation(x, y)
|
99
|
+
end
|
100
|
+
|
101
|
+
def swap(x, y)
|
102
|
+
temp = store[y]
|
103
|
+
store[y] = store[x]
|
104
|
+
store[x] = temp
|
105
|
+
end
|
101
106
|
end
|
102
107
|
end
|