ds 0.0.1

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 (120) hide show
  1. data/.gitignore +4 -0
  2. data/Gemfile +4 -0
  3. data/Rakefile +13 -0
  4. data/doc/Array.html +264 -0
  5. data/doc/DS.html +292 -0
  6. data/doc/DS/Array2D.html +345 -0
  7. data/doc/DS/BinaryHeap.html +493 -0
  8. data/doc/DS/BinarySearchTree.html +313 -0
  9. data/doc/DS/BinaryTree.html +433 -0
  10. data/doc/DS/CompleteBinaryTree.html +550 -0
  11. data/doc/DS/CyclicList.html +234 -0
  12. data/doc/DS/Digraph.html +299 -0
  13. data/doc/DS/Edge.html +283 -0
  14. data/doc/DS/ExpandableArray.html +316 -0
  15. data/doc/DS/Graph.html +739 -0
  16. data/doc/DS/GraphAsList.html +361 -0
  17. data/doc/DS/GraphAsMatrix.html +633 -0
  18. data/doc/DS/GraphAsTriMatrix.html +274 -0
  19. data/doc/DS/List.html +1263 -0
  20. data/doc/DS/ListElement.html +344 -0
  21. data/doc/DS/Queue.html +517 -0
  22. data/doc/DS/Ring.html +323 -0
  23. data/doc/DS/Stack.html +407 -0
  24. data/doc/DS/Tree.html +770 -0
  25. data/doc/DS/TreeWalker.html +561 -0
  26. data/doc/DS/TriMatrix.html +338 -0
  27. data/doc/created.rid +25 -0
  28. data/doc/ds/graphs/digraph_rb.html +52 -0
  29. data/doc/ds/graphs/edge_rb.html +52 -0
  30. data/doc/ds/graphs/graph_as_list_rb.html +52 -0
  31. data/doc/ds/graphs/graph_as_matrix_rb.html +52 -0
  32. data/doc/ds/graphs/graph_as_tri_matrix_rb.html +52 -0
  33. data/doc/ds/graphs/graph_rb.html +52 -0
  34. data/doc/ds/lists/cyclic_list_rb.html +52 -0
  35. data/doc/ds/lists/list_element_rb.html +52 -0
  36. data/doc/ds/lists/list_rb.html +52 -0
  37. data/doc/ds/lists/ring_rb.html +52 -0
  38. data/doc/ds/matrixes/array_2d_rb.html +52 -0
  39. data/doc/ds/matrixes/expandable_array_rb.html +52 -0
  40. data/doc/ds/matrixes/tri_matrix_rb.html +52 -0
  41. data/doc/ds/queues/queue_rb.html +52 -0
  42. data/doc/ds/stacks/stack_rb.html +52 -0
  43. data/doc/ds/trees/binary_heap_rb.html +52 -0
  44. data/doc/ds/trees/binary_search_tree_rb.html +52 -0
  45. data/doc/ds/trees/binary_tree_rb.html +52 -0
  46. data/doc/ds/trees/complete_binary_tree_rb.html +52 -0
  47. data/doc/ds/trees/tree_rb.html +52 -0
  48. data/doc/ds/trees/tree_walker_rb.html +52 -0
  49. data/doc/ds/version_rb.html +52 -0
  50. data/doc/ds_rb.html +98 -0
  51. data/doc/ext/ext_rb.html +52 -0
  52. data/doc/images/brick.png +0 -0
  53. data/doc/images/brick_link.png +0 -0
  54. data/doc/images/bug.png +0 -0
  55. data/doc/images/bullet_black.png +0 -0
  56. data/doc/images/bullet_toggle_minus.png +0 -0
  57. data/doc/images/bullet_toggle_plus.png +0 -0
  58. data/doc/images/date.png +0 -0
  59. data/doc/images/find.png +0 -0
  60. data/doc/images/loadingAnimation.gif +0 -0
  61. data/doc/images/macFFBgHack.png +0 -0
  62. data/doc/images/package.png +0 -0
  63. data/doc/images/page_green.png +0 -0
  64. data/doc/images/page_white_text.png +0 -0
  65. data/doc/images/page_white_width.png +0 -0
  66. data/doc/images/plugin.png +0 -0
  67. data/doc/images/ruby.png +0 -0
  68. data/doc/images/tag_green.png +0 -0
  69. data/doc/images/wrench.png +0 -0
  70. data/doc/images/wrench_orange.png +0 -0
  71. data/doc/images/zoom.png +0 -0
  72. data/doc/index.html +375 -0
  73. data/doc/js/darkfish.js +116 -0
  74. data/doc/js/jquery.js +32 -0
  75. data/doc/js/quicksearch.js +114 -0
  76. data/doc/js/thickbox-compressed.js +10 -0
  77. data/doc/rdoc.css +763 -0
  78. data/ds.gemspec +20 -0
  79. data/lib/ds.rb +38 -0
  80. data/lib/ds/graphs/digraph.rb +20 -0
  81. data/lib/ds/graphs/edge.rb +15 -0
  82. data/lib/ds/graphs/graph.rb +107 -0
  83. data/lib/ds/graphs/graph_as_list.rb +48 -0
  84. data/lib/ds/graphs/graph_as_matrix.rb +114 -0
  85. data/lib/ds/graphs/graph_as_tri_matrix.rb +25 -0
  86. data/lib/ds/lists/cyclic_list.rb +21 -0
  87. data/lib/ds/lists/list.rb +303 -0
  88. data/lib/ds/lists/list_element.rb +26 -0
  89. data/lib/ds/lists/ring.rb +42 -0
  90. data/lib/ds/matrixes/array_2d.rb +35 -0
  91. data/lib/ds/matrixes/expandable_array.rb +37 -0
  92. data/lib/ds/matrixes/tri_matrix.rb +30 -0
  93. data/lib/ds/queues/queue.rb +53 -0
  94. data/lib/ds/stacks/stack.rb +39 -0
  95. data/lib/ds/trees/binary_heap.rb +71 -0
  96. data/lib/ds/trees/binary_search_tree.rb +32 -0
  97. data/lib/ds/trees/binary_tree.rb +65 -0
  98. data/lib/ds/trees/complete_binary_tree.rb +52 -0
  99. data/lib/ds/trees/tree.rb +117 -0
  100. data/lib/ds/trees/tree_walker.rb +179 -0
  101. data/lib/ds/version.rb +3 -0
  102. data/lib/ext/ext.rb +15 -0
  103. data/test/help.rb +8 -0
  104. data/test/test_array2d.rb +51 -0
  105. data/test/test_binary_heap.rb +35 -0
  106. data/test/test_binary_search_tree.rb +32 -0
  107. data/test/test_binary_tree.rb +51 -0
  108. data/test/test_complete_binary_tree.rb +30 -0
  109. data/test/test_digraph.rb +134 -0
  110. data/test/test_expandable_array.rb +26 -0
  111. data/test/test_graph.rb +71 -0
  112. data/test/test_list.rb +138 -0
  113. data/test/test_list_element.rb +56 -0
  114. data/test/test_queue.rb +110 -0
  115. data/test/test_ring.rb +28 -0
  116. data/test/test_stack.rb +87 -0
  117. data/test/test_tree.rb +48 -0
  118. data/test/test_tree_walker.rb +69 -0
  119. data/test/test_tri_matrix.rb +22 -0
  120. metadata +184 -0
@@ -0,0 +1,117 @@
1
+ module DS
2
+ class Tree
3
+
4
+ include Enumerable
5
+
6
+ attr_accessor :data
7
+ attr_reader :children
8
+
9
+ #Returns a new tree.
10
+ def initialize(value=nil)
11
+ @data = value
12
+ @children = []
13
+ end
14
+
15
+ #Inserts a new subtree.
16
+ def << (value)
17
+ subtree = Tree.new(value)
18
+ @children << subtree
19
+ return subtree
20
+ end
21
+
22
+ #Checks if node is leaf.
23
+ def leaf?
24
+ self.children.empty?
25
+ end
26
+
27
+ #Returns leaf list.
28
+ def get_leaves(tree=self)
29
+ list = List.new
30
+ walker = TreeWalker.new(self)
31
+ walker.traverse(:postorder){|t| list.append(t) if t.leaf? }
32
+ list
33
+ end
34
+
35
+ #Returns the number of leaves for given subtree.
36
+ def leaf_count(tree=self)
37
+ if tree.leaf?
38
+ 1
39
+ else
40
+ tree.children.inject(0){|m,t| m += leaf_count(t)}
41
+ end
42
+ end
43
+
44
+
45
+ #Returns number of nodes for each tree level.
46
+ #{1=>1, 2=>4, 3=>5}
47
+ def levels
48
+ walker = TreeWalker.new(self)
49
+ nodes={}
50
+
51
+ walker.traverse_with_h(self,1) do |t,level|
52
+ if nodes[level]
53
+ nodes[level] += 1
54
+ else
55
+ nodes[level] = 1
56
+ end
57
+ end
58
+ nodes
59
+ end
60
+
61
+ #Returns tree width.
62
+ def width
63
+ levels.values.max
64
+ end
65
+
66
+ #Returns subtree height.
67
+ def h(tree)
68
+ unless tree.leaf?
69
+ tree.children.map{|t| h(t) }.max + 1
70
+ else
71
+ 1
72
+ end
73
+ end
74
+
75
+ #Returns tree height.
76
+ def height
77
+ h(self)
78
+ end
79
+
80
+ #Returns node which lies closest to the root.
81
+ def lowest_height
82
+ find{ |node| node.leaf? }.data
83
+ end
84
+
85
+ #Mirrors tree.
86
+ def mirror!(tree=self)
87
+ unless tree.leaf?
88
+ tree.children.reverse!
89
+ tree.children.each{|t| mirror!(t)}
90
+ end
91
+ end
92
+
93
+ #Checks if tree is isometric to another tree.
94
+ def izometric?(other)
95
+ tree = self
96
+ unless tree.leaf? and other.leaf?
97
+ if tree.children.size == other.children.size
98
+ tree.children.each_with_index{|t,i| return false unless t.izometric?(other.children[i])}
99
+ else
100
+ return false
101
+ end
102
+ end
103
+ return true
104
+ end
105
+
106
+
107
+ #Iterates tree in BFS order.
108
+ def each
109
+ TreeWalker.new(self).traverse{ |t| yield t }
110
+ end
111
+
112
+ def to_a
113
+ map{ |node| node.data }
114
+ end
115
+ end
116
+ end
117
+
@@ -0,0 +1,179 @@
1
+ module DS
2
+ class TreeWalker
3
+
4
+ attr_accessor :visited
5
+ attr_accessor :tree
6
+
7
+
8
+ #Creates new tree iterator.
9
+ def initialize(tree=nil)
10
+ @visited = []
11
+ @tree = tree
12
+ end
13
+
14
+
15
+ #Traversing tree in given order:
16
+ #bfs - Breadth-first search - default
17
+ #postorder - postorder search
18
+ #preorder - preorder search
19
+ #inorder - inorder search - only for Binary Trees
20
+ #
21
+ #If block is given, passes each visited subtree to block.
22
+ #Returns values of nodes in given order
23
+
24
+ def traverse(order=:bfs,&block)
25
+ reset
26
+ tree = @tree
27
+
28
+ case order
29
+ when :bfs
30
+ traverse_bfs &block
31
+ when :postorder
32
+ walk(tree,:postorder,&block)
33
+ when :preorder
34
+ walk(tree,:preorder, &block)
35
+ when (:inorder)
36
+ raise ArgumentError unless tree.kind_of? BinaryTree
37
+ walk(tree,order,&block)
38
+ end
39
+
40
+ return visited
41
+ end
42
+
43
+ #Traverses tree in BFS order.
44
+ def traverse_bfs
45
+ q = Queue.new
46
+ q.push @tree
47
+
48
+ loop do
49
+ break if q.empty?
50
+ node = q.shift
51
+ if block_given?
52
+ yield node
53
+ else
54
+ @visited << node.data
55
+ end
56
+ node.children.each{ |n| q.push n } if node.children
57
+ end
58
+ end
59
+
60
+ #Resets tree walker.
61
+ def reset
62
+ @visited.clear
63
+ self
64
+ end
65
+
66
+
67
+
68
+ def traverse_with_h(tree,height=nil,&block)
69
+
70
+ tree.children.each do |t|
71
+ traverse_with_h(t,height+1,&block)
72
+ end
73
+
74
+ if block_given?
75
+ yield tree, height
76
+ else
77
+ @visited << tree.data
78
+ end
79
+
80
+ end
81
+
82
+
83
+ #Recalculates tree by evaluating block on every node.
84
+ def recalculate!(tree,order,memo=nil,&block)
85
+ if tree
86
+
87
+ case order
88
+ when :postorder
89
+
90
+ arr = tree.children.map{ |t| recalculate!(t,order,memo,&block) }
91
+ result = block.call(arr.push tree.data)
92
+ tree.data = result
93
+
94
+
95
+ when :preorder
96
+
97
+ tree.data = yield tree, memo
98
+ memo = tree.data
99
+
100
+ tree.children.each do |t|
101
+ recalculate!(t,order,memo,&block)
102
+ end
103
+
104
+ when :inorder
105
+ raise ArgumentError unless self.tree.is_a? BinaryTree
106
+ recalculate!(tree.left,order,&block)
107
+
108
+ tree.data = yield tree.memo
109
+ memo = tree.data
110
+
111
+ recalculate!(tree.right,order,memo,&block)
112
+
113
+ end
114
+ end
115
+ end
116
+
117
+
118
+
119
+ #Summarize tree
120
+ def summarize(direction=:bottomup)
121
+
122
+ case direction
123
+ when :bottomup
124
+ recalculate!(self.tree,:postorder,0){|ar| ar.inject(0){|x,memo| memo += x}}
125
+ self.tree
126
+ when :topdown
127
+ recalculate!(self.tree,:preorder,0){|x,memo| memo = memo+x.data}
128
+ self.tree
129
+ end
130
+ end
131
+
132
+
133
+
134
+ private
135
+
136
+ def walk(tree,order,&block)
137
+ if tree
138
+
139
+ case order
140
+ when :postorder
141
+ tree.children.each do |t|
142
+ walk(t,order,&block)
143
+ end
144
+
145
+ if block_given?
146
+ yield tree
147
+ else
148
+ @visited << tree.data
149
+ end
150
+
151
+ when :preorder
152
+ if block_given?
153
+ yield tree
154
+ else
155
+ @visited << tree.data
156
+ end
157
+
158
+ tree.children.each do |t|
159
+ walk(t,order,&block)
160
+ end
161
+
162
+ when :inorder
163
+ raise ArgumentError unless self.tree.is_a? BinaryTree
164
+ walk(tree.left,order,&block)
165
+
166
+ if block_given?
167
+ yield tree
168
+ else
169
+ @visited << tree.data
170
+ end
171
+
172
+ walk(tree.right,order,&block)
173
+
174
+ end
175
+ end
176
+ end
177
+ end
178
+ end
179
+
@@ -0,0 +1,3 @@
1
+ module DS
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,15 @@
1
+ class Array
2
+ def sorted?(order = :growing)
3
+ (size-2).times{ |i| return false if self[i] > self[i+1] }
4
+ true
5
+ end
6
+
7
+ def push_uniq e
8
+ if include? e
9
+ index e
10
+ else
11
+ push e
12
+ size-1
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,8 @@
1
+ require 'rubygems'
2
+ require 'minitest/autorun'
3
+ require "minitest/benchmark" if ENV['BENCH']
4
+ require 'redgreen'
5
+
6
+ require 'ds'
7
+ include DS
8
+
@@ -0,0 +1,51 @@
1
+ require 'help'
2
+
3
+ describe Array2D do
4
+
5
+ describe "initialized with 0" do
6
+
7
+ before do
8
+ @zero_matrix = Array2D.new(2,0)
9
+ end
10
+
11
+ it "should return zero for any index." do
12
+ @zero_matrix[1,1].must_equal 0
13
+ @zero_matrix[0,0].must_equal 0
14
+ end
15
+
16
+ it "#to_a should return matrix flattened to array." do
17
+ @zero_matrix.to_a.must_be_instance_of Array
18
+ @zero_matrix.to_a.must_equal [0,0,0,0]
19
+ end
20
+
21
+ it "#should extend magically." do
22
+ @zero_matrix[3,3].must_equal 0
23
+ @zero_matrix[4,8].wont_be_nil
24
+ end
25
+ end
26
+
27
+ describe "initialized with false" do
28
+
29
+ before do
30
+ @discrete_matrix = Array2D.new(3,false)
31
+ end
32
+
33
+ it "should return false for any index." do
34
+ refute @discrete_matrix[1,1]
35
+ refute @discrete_matrix[0,0]
36
+ end
37
+
38
+ it "#to_a should return matrix flattened to array." do
39
+ @discrete_matrix.to_a.must_be_instance_of Array
40
+ @discrete_matrix.to_a.must_equal [false,false,false,false,false,false,false,false,false]
41
+ end
42
+
43
+ it "#should extend magically." do
44
+ refute @discrete_matrix[3,3]
45
+ @discrete_matrix[4,8].wont_be_nil
46
+ end
47
+
48
+ end
49
+ end
50
+
51
+
@@ -0,0 +1,35 @@
1
+ require "help"
2
+
3
+ describe BinaryHeap do
4
+
5
+ before do
6
+ @arr = [9,8,4,5,11,6]
7
+ @arr2 = [4,2,9,11,3,5,1]
8
+ @heap = BinaryHeap.new(*@arr)
9
+ @heap2 = BinaryHeap.new(*@arr2)
10
+ end
11
+
12
+ it "should create heap from array" do
13
+ @heap.to_a.must_equal [11,9,6,5,8,4]
14
+ @heap2.to_a.must_equal [11,4,9,2,3,5,1]
15
+ end
16
+
17
+ it "#insert should insert new element to the heap maintaining heap relation." do
18
+ @heap.insert(13).to_a.must_equal [13,9,11,5,8,4,6]
19
+ end
20
+
21
+ describe "Minimal Heap" do
22
+
23
+ before do
24
+ @min_heap = BinaryHeap.new(*@arr){|parent,child| parent < child}
25
+ end
26
+
27
+ it "should create heap from array." do
28
+ @min_heap.to_a.must_equal [4,5,6,8,11,9]
29
+ end
30
+
31
+ it "#insert should insert new element to the heap maintaining heap relation." do
32
+ @min_heap.insert(3).to_a.must_equal [3,5,4,8,11,9,6]
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,32 @@
1
+ require 'help'
2
+
3
+ describe BinarySearchTree do
4
+
5
+ before do
6
+ t = BinarySearchTree.new(7)
7
+ c1 = t.insert 5
8
+ c2 = t.insert 8
9
+
10
+ c3 = c1.insert 2
11
+ c1.insert 6
12
+
13
+ c3.insert 1
14
+
15
+ @bst = t
16
+
17
+ @bin_tree = BinaryTree.new
18
+ [2,5,8,9,11,12,14].each{|x| @bin_tree.insert(x)}
19
+
20
+ end
21
+
22
+ it "should be valid Binary Search Tree." do
23
+ assert BinarySearchTree.valid?(@bst)
24
+ end
25
+
26
+
27
+ it "not every Binary Tree is valid Binary Search Tree." do
28
+ refute BinarySearchTree.valid?(@bin_tree)
29
+ end
30
+
31
+ end
32
+