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.
Files changed (75) hide show
  1. checksums.yaml +7 -0
  2. data/.rubocop.yml +11 -0
  3. data/.rubocop_todo.yml +452 -0
  4. data/.travis.yml +12 -0
  5. data/Gemfile +1 -1
  6. data/README.rdoc +185 -214
  7. data/Rakefile +8 -3
  8. data/ds.gemspec +16 -13
  9. data/lib/ds.rb +20 -30
  10. data/lib/ds/{matrixes → arrays}/array_2d.rb +9 -10
  11. data/lib/ds/arrays/expandable_array.rb +34 -0
  12. data/lib/ds/arrays/heap_store.rb +32 -0
  13. data/lib/ds/arrays/tri_matrix.rb +33 -0
  14. data/lib/ds/lists/list.rb +310 -186
  15. data/lib/ds/lists/list_element.rb +14 -11
  16. data/lib/ds/pair.rb +4 -4
  17. data/lib/ds/queues/priority_queue.rb +33 -20
  18. data/lib/ds/queues/simple_queue.rb +55 -0
  19. data/lib/ds/sets/indexed_set.rb +37 -0
  20. data/lib/ds/stacks/stack.rb +25 -17
  21. data/lib/ds/trees/binary_heap.rb +71 -66
  22. data/lib/ds/trees/binary_tree.rb +40 -44
  23. data/lib/ds/trees/red_black_tree.rb +123 -0
  24. data/lib/ds/trees/red_black_tree/node.rb +21 -0
  25. data/lib/ds/trees/tree.rb +50 -48
  26. data/lib/ds/trees/tree_walker.rb +73 -144
  27. data/lib/ds/trees/trie.rb +67 -37
  28. data/lib/ds/trees/trie/node.rb +48 -0
  29. data/lib/ds/version.rb +2 -1
  30. data/test/help.rb +3 -6
  31. data/test/performance/binary_heap_performance_test.rb +20 -0
  32. data/test/performance/list_performance_test.rb +36 -0
  33. data/test/performance/priority_queue_performance.rb +32 -0
  34. data/test/performance/rbt_performance_test.rb +17 -0
  35. data/test/performance/simple_queue_performance_test.rb +37 -0
  36. data/test/performance/stack_test.rb +45 -0
  37. data/test/test_array2d.rb +29 -31
  38. data/test/test_binary_heap.rb +29 -23
  39. data/test/test_binary_tree.rb +30 -20
  40. data/test/test_expandable_array.rb +6 -10
  41. data/test/test_heap_store.rb +34 -0
  42. data/test/test_indexed_set.rb +26 -0
  43. data/test/test_list.rb +226 -109
  44. data/test/test_list_element.rb +34 -16
  45. data/test/test_pair.rb +5 -8
  46. data/test/test_priority_queue.rb +43 -64
  47. data/test/test_queue.rb +12 -61
  48. data/test/test_red_black_tree.rb +46 -0
  49. data/test/test_stack.rb +35 -39
  50. data/test/test_tree.rb +42 -29
  51. data/test/test_tree_walker.rb +27 -52
  52. data/test/test_tri_matrix.rb +6 -11
  53. data/test/test_trie.rb +59 -17
  54. metadata +80 -35
  55. data/lib/ds/ext/array_x.rb +0 -35
  56. data/lib/ds/graphs/digraph.rb +0 -20
  57. data/lib/ds/graphs/edge.rb +0 -15
  58. data/lib/ds/graphs/graph.rb +0 -111
  59. data/lib/ds/graphs/graph_as_matrix.rb +0 -113
  60. data/lib/ds/graphs/graph_as_tri_matrix.rb +0 -24
  61. data/lib/ds/lists/cyclic_list.rb +0 -21
  62. data/lib/ds/lists/ring.rb +0 -42
  63. data/lib/ds/matrixes/expandable_array.rb +0 -37
  64. data/lib/ds/matrixes/tri_matrix.rb +0 -30
  65. data/lib/ds/queues/queue.rb +0 -53
  66. data/lib/ds/sets/ordered_set.rb +0 -32
  67. data/lib/ds/trees/binary_search_tree.rb +0 -34
  68. data/lib/ds/trees/complete_binary_tree.rb +0 -60
  69. data/test/test_array_x.rb +0 -51
  70. data/test/test_binary_search_tree.rb +0 -39
  71. data/test/test_complete_binary_tree.rb +0 -58
  72. data/test/test_digraph.rb +0 -134
  73. data/test/test_graph.rb +0 -80
  74. data/test/test_ordered_set.rb +0 -28
  75. 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
- attr_accessor :data, :next
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
-
@@ -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 :first :key
6
- alias :second :value
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
- class PriorityQueue < Queue
3
-
4
- #Create new priority queue. Internaly uses heap to store elements.
5
- def initialize
6
- @store = BinaryHeap.new {|parent,child| parent.key >= child.key}
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
- #Adds element to queue with given priority.
11
- def enqueue x, priority
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
- #Removes element with highest priority from queue .
22
+ alias push enqueue
23
+
24
+ # Removes element with highest priority from queue.
20
25
  def dequeue
21
- if x = @store.shift
22
- x.value
23
- else
24
- x
25
- end
26
+ x = @store.shift
27
+ x ? x.value : nil
26
28
  end
27
29
 
28
- alias :shift :dequeue
30
+ alias shift dequeue
29
31
 
30
- #Returns element with highest priority.
32
+ # Returns element with highest priority.
31
33
  def peek
32
- @store.data.first.value
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
@@ -1,39 +1,47 @@
1
1
  module DS
2
-
3
- #Class implements Stack data structure.
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
- def initialize
9
- @store = []
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
- @store.size
20
+ store.size
15
21
  end
16
22
 
17
23
  # Removes element from stack and returns it.
18
24
  def pop
19
- @store.pop
25
+ store.pop unless empty?
20
26
  end
21
-
22
- # Adds element to the top of the stack.
27
+
28
+ # Adds element on the top of the stack.
23
29
  def push(x)
24
- @store.push x
30
+ store.push x
25
31
  end
26
32
 
27
33
  # Returns element from the top of the stack.
28
34
  def peek
29
- @store.last
35
+ store.last
30
36
  end
31
37
 
32
38
  # If stack is empty returns true otherwise returns false.
33
39
  def empty?
34
- @store.empty?
40
+ store.empty?
35
41
  end
36
- end
37
- end
38
42
 
43
+ protected
39
44
 
45
+ attr_reader :store
46
+ end
47
+ end
@@ -1,102 +1,107 @@
1
1
  module DS
2
- class BinaryHeap < CompleteBinaryTree
3
- attr_accessor :data
4
-
5
- #Create new Heap from args.
6
- #Given block sets the heap relation. Default heap relation is Max Heap.
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
- @relation = block
10
- else
11
- @relation = Proc.new{|parent,child| parent >= child}
12
- end
13
- @data = args.to_a
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 BinaryHeap.max(*args)
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 BinaryHeap.min(*args)
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
- #Evaluates Heap relation.
29
- def relation(parent,child)
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
- (@data.size/2).downto(0) do |i|
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
- if @data.size > 0
61
- result = @data.shift
62
- return result if @data.size.zero?
63
- @data.unshift @data.pop
64
- heapify(0)
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
- @data.push value
74
- child = @data.size-1
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
- @data.size
64
+ store.length
89
65
  end
90
66
 
91
- alias :size :length
67
+ alias size length
92
68
 
93
69
  def empty?
94
- @data.empty?
70
+ store.empty?
95
71
  end
96
72
 
97
73
  def to_a
98
- @data
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