ds 0.0.4 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
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