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
data/test/test_stack.rb
CHANGED
@@ -1,85 +1,81 @@
|
|
1
1
|
require 'help'
|
2
2
|
|
3
|
-
describe
|
4
|
-
|
3
|
+
describe Stack do
|
5
4
|
before do
|
6
|
-
@stack = Stack.new
|
7
|
-
@stack.push :first
|
8
|
-
@stack.push :second
|
5
|
+
@stack = Stack.new(:first, :second)
|
9
6
|
end
|
10
7
|
|
11
|
-
describe
|
12
|
-
|
8
|
+
describe 'Empty stack' do
|
13
9
|
before do
|
14
10
|
@empty_stack = Stack.new
|
15
11
|
end
|
16
12
|
|
17
|
-
it
|
13
|
+
it 'should be empty.' do
|
18
14
|
assert @empty_stack.empty?
|
19
15
|
@empty_stack.size.must_equal 0
|
20
16
|
end
|
21
17
|
|
22
|
-
it
|
18
|
+
it '#pop should retrun nil.' do
|
23
19
|
@empty_stack.pop.must_be_nil
|
24
20
|
end
|
25
21
|
|
26
|
-
it
|
27
|
-
@empty_stack.peek.must_be_nil
|
22
|
+
it '#peek should return nil.' do
|
23
|
+
@empty_stack.peek.must_be_nil
|
28
24
|
end
|
29
25
|
|
30
|
-
it
|
26
|
+
it '#push should change stack size.' do
|
31
27
|
@empty_stack.push :first
|
32
28
|
refute @empty_stack.empty?
|
33
29
|
@empty_stack.size.must_equal 1
|
34
30
|
end
|
35
31
|
end
|
36
32
|
|
33
|
+
describe 'Not empty stack implemented as List' do
|
34
|
+
before do
|
35
|
+
@stack = Stack.create(:first, :second)
|
36
|
+
end
|
37
37
|
|
38
|
-
|
39
|
-
|
40
|
-
it "should not be empty." do
|
38
|
+
it 'should not be empty.' do
|
41
39
|
refute @stack.empty?
|
42
40
|
end
|
43
41
|
|
44
|
-
it
|
42
|
+
it '#peek should return element from the top of the stack.' do
|
45
43
|
@stack.peek.must_equal :second
|
46
44
|
end
|
47
45
|
|
48
|
-
it
|
49
|
-
@stack.pop
|
46
|
+
it '#pop should remove element form the top of the stack.' do
|
47
|
+
last = @stack.pop
|
48
|
+
last.must_equal :second
|
50
49
|
@stack.size.must_equal 1
|
51
50
|
@stack.peek.must_equal :first
|
52
51
|
end
|
53
52
|
|
54
|
-
it
|
53
|
+
it '#push should insert element to the top of the stack.' do
|
55
54
|
@stack.push(:third)
|
56
55
|
@stack.peek.must_equal :third
|
57
56
|
@stack.size.must_equal 3
|
58
57
|
end
|
58
|
+
end
|
59
59
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
100000.times do |n|
|
65
|
-
@stack.push 4
|
66
|
-
end
|
67
|
-
end
|
60
|
+
describe 'Not empty stack implemented as Array' do
|
61
|
+
it 'should not be empty.' do
|
62
|
+
refute @stack.empty?
|
63
|
+
end
|
68
64
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
end
|
73
|
-
end
|
65
|
+
it '#peek should return element from the top of the stack.' do
|
66
|
+
@stack.peek.must_equal :second
|
67
|
+
end
|
74
68
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
69
|
+
it '#pop should remove element form the top of the stack.' do
|
70
|
+
@stack.pop
|
71
|
+
@stack.size.must_equal 1
|
72
|
+
@stack.peek.must_equal :first
|
73
|
+
end
|
80
74
|
|
81
|
-
|
75
|
+
it '#push should insert element to the top of the stack.' do
|
76
|
+
@stack.push(:third)
|
77
|
+
@stack.peek.must_equal :third
|
78
|
+
@stack.size.must_equal 3
|
82
79
|
end
|
83
80
|
end
|
84
81
|
end
|
85
|
-
|
data/test/test_tree.rb
CHANGED
@@ -1,71 +1,84 @@
|
|
1
1
|
require 'help'
|
2
2
|
|
3
3
|
describe Tree do
|
4
|
-
|
5
4
|
before do
|
6
5
|
t = Tree.new(2)
|
7
|
-
|
8
|
-
|
9
|
-
t << 9
|
6
|
+
@child1 = t << 5
|
7
|
+
@child2 = t << 8
|
8
|
+
@child3 = t << 9
|
10
9
|
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
@grand1 = @child1 << 4
|
11
|
+
@grand2 = @child1 << 10
|
12
|
+
@grand3 = @child2 << 3
|
14
13
|
|
15
14
|
@tree = t
|
16
15
|
end
|
17
|
-
|
18
|
-
it
|
19
|
-
@tree.to_a.must_equal [2,5,8,9,4,10,3]
|
16
|
+
|
17
|
+
it '#to_a should return tree converted to array.' do
|
18
|
+
@tree.to_a.must_equal [2, 5, 8, 9, 4, 10, 3]
|
20
19
|
end
|
21
20
|
|
22
|
-
it
|
21
|
+
it '<< should add new subtree to tree.' do
|
23
22
|
subtree = @tree << 7
|
24
23
|
subtree.must_be_kind_of Tree
|
25
24
|
@tree.children.size.must_equal 4
|
26
25
|
end
|
27
26
|
|
28
|
-
it
|
27
|
+
it '#parent should return node parent' do
|
28
|
+
@child1.parent.must_equal @tree
|
29
|
+
@child2.parent.must_equal @tree
|
30
|
+
@grand1.parent.must_equal @child1
|
31
|
+
@grand3.parent.must_equal @child2
|
32
|
+
end
|
33
|
+
|
34
|
+
it '#sibblings should return node sibblings' do
|
35
|
+
@child1.sibblings.must_equal [@child2, @child3]
|
36
|
+
@child2.sibblings.must_equal [@child1, @child3]
|
37
|
+
@grand1.sibblings.must_equal [@grand2]
|
38
|
+
@grand3.sibblings.must_equal []
|
39
|
+
end
|
40
|
+
|
41
|
+
it '#leaf? should check if node is a leaf.' do
|
29
42
|
refute @tree.leaf?
|
30
43
|
assert @tree.children.last.leaf?
|
31
44
|
end
|
32
45
|
|
33
|
-
it
|
46
|
+
it '#children returns node child nodes.' do
|
47
|
+
@tree.children.map(&:data).must_equal([5, 8, 9])
|
48
|
+
end
|
49
|
+
|
50
|
+
it '#get_leaves should return list of tree leaves.' do
|
34
51
|
leaves = @tree.get_leaves
|
35
52
|
leaves.must_be_kind_of List
|
36
|
-
leaves.to_a.collect
|
53
|
+
leaves.to_a.collect(&:data).must_equal [4, 10, 3, 9]
|
37
54
|
end
|
38
55
|
|
39
|
-
it
|
56
|
+
it '#leaf_count should return number of tree leaves.' do
|
40
57
|
@tree.leaf_count.must_equal 4
|
41
58
|
end
|
42
59
|
|
43
|
-
it
|
44
|
-
@tree.levels.must_equal 1 => 1, 2 => 3, 3 => 3
|
60
|
+
it '#levels should return number of nodes on each tree level.' do
|
61
|
+
@tree.levels.must_equal 1 => 1, 2 => 3, 3 => 3
|
45
62
|
end
|
46
63
|
|
47
|
-
|
48
|
-
it "#height should return tree height." do
|
64
|
+
it '#height should return tree height.' do
|
49
65
|
@tree.height.must_equal 3
|
50
66
|
end
|
51
67
|
|
52
|
-
it
|
68
|
+
it 'Tree.h should return subtree height.' do
|
53
69
|
Tree.h(@tree.children.last).must_equal 1
|
54
70
|
end
|
55
71
|
|
56
|
-
it
|
72
|
+
it '#width should return tree width.' do
|
57
73
|
@tree.width.must_equal 3
|
58
74
|
end
|
59
75
|
|
60
|
-
|
61
|
-
|
62
|
-
@tree.lowest_height.data.must_equal 9
|
76
|
+
it '#lowest_height should return node which lies closest to the root.' do
|
77
|
+
@tree.lowest_height.data.must_equal 9
|
63
78
|
end
|
64
79
|
|
65
|
-
it
|
66
|
-
|
67
|
-
|
80
|
+
it '#mirror! should mirror tree.' do
|
81
|
+
@tree.mirror!
|
82
|
+
@tree.to_a.must_equal [2, 9, 8, 5, 3, 10, 4]
|
68
83
|
end
|
69
|
-
|
70
84
|
end
|
71
|
-
|
data/test/test_tree_walker.rb
CHANGED
@@ -1,91 +1,66 @@
|
|
1
|
-
require
|
1
|
+
require 'help'
|
2
2
|
|
3
3
|
describe TreeWalker do
|
4
|
-
|
5
|
-
describe "traversing Tree" do
|
6
|
-
|
4
|
+
describe 'traversing Tree' do
|
7
5
|
before do
|
8
|
-
|
9
6
|
t = Tree.new(2)
|
10
7
|
c1 = t << 5
|
11
8
|
c2 = t << 8
|
12
9
|
t << 9
|
13
|
-
|
14
10
|
c1 << 4
|
15
11
|
c1 << 10
|
16
12
|
c2 << 3
|
17
13
|
|
18
14
|
@tree = t
|
19
|
-
|
20
|
-
@walker = TreeWalker.new(@tree)
|
15
|
+
@walker = TreeWalker.new(@tree)
|
21
16
|
end
|
22
17
|
|
23
|
-
|
24
|
-
|
25
|
-
@walker.traverse.must_equal [2,5,8,9,4,10,3]
|
18
|
+
it '#traverse without arguments should traverse tree in BFS order.' do
|
19
|
+
@walker.traverse.must_equal [2, 5, 8, 9, 4, 10, 3]
|
26
20
|
end
|
27
21
|
|
28
|
-
it
|
29
|
-
@walker.traverse(:bfs).must_equal [2,5,8,9,4,10,3]
|
30
|
-
end
|
31
|
-
|
32
|
-
it "#summarize should transform tree." do
|
33
|
-
@walker.summarize(:topdown).to_a.must_equal [2,7,10,11,11,17,13]
|
22
|
+
it 'should traverse in BFS order.' do
|
23
|
+
@walker.traverse(:bfs).must_equal [2, 5, 8, 9, 4, 10, 3]
|
34
24
|
end
|
35
25
|
end
|
36
26
|
|
37
|
-
describe
|
38
|
-
|
27
|
+
describe 'traversing Binary Tree' do
|
39
28
|
before do
|
40
29
|
@bin_tree = BinaryTree.new
|
41
|
-
[2,5,8,9,11,12,14].each{|x| @bin_tree.insert(x)}
|
42
|
-
@bin_walker =
|
30
|
+
[2, 5, 8, 9, 11, 12, 14].each { |x| @bin_tree.insert(x) }
|
31
|
+
@bin_walker = TreeWalker.new(@bin_tree)
|
43
32
|
end
|
44
33
|
|
45
|
-
it
|
46
|
-
@bin_walker.traverse.must_equal [2,5,8,9,11,12,14]
|
34
|
+
it '#traverse without arguments should traverse tree in BFS order.' do
|
35
|
+
@bin_walker.traverse.must_equal [2, 5, 8, 9, 11, 12, 14]
|
47
36
|
end
|
48
37
|
|
49
|
-
it
|
50
|
-
@bin_walker.traverse(:bfs).must_equal [2,5,8,9,11,12,14]
|
51
|
-
|
38
|
+
it 'should traverse in BFS order.' do
|
39
|
+
@bin_walker.traverse(:bfs).must_equal [2, 5, 8, 9, 11, 12, 14]
|
52
40
|
end
|
53
41
|
|
54
|
-
it
|
55
|
-
@bin_walker.traverse(:preorder).must_equal
|
42
|
+
it 'should traverse in preorder.' do
|
43
|
+
@bin_walker.traverse(:preorder).must_equal [2, 5, 9, 11, 8, 12, 14]
|
56
44
|
|
57
45
|
arr = []
|
58
|
-
@bin_walker.traverse(:preorder){|t| arr << t.data}
|
59
|
-
arr.must_equal
|
46
|
+
@bin_walker.traverse(:preorder) { |t| arr << t.data }
|
47
|
+
arr.must_equal [2, 5, 9, 11, 8, 12, 14]
|
60
48
|
end
|
61
49
|
|
62
|
-
|
63
|
-
|
64
|
-
@bin_walker.traverse(:postorder).must_equal [9,11,5,12,14,8,2]
|
50
|
+
it 'should traverse in postorder.' do
|
51
|
+
@bin_walker.traverse(:postorder).must_equal [9, 11, 5, 12, 14, 8, 2]
|
65
52
|
|
66
53
|
arr = []
|
67
|
-
@bin_walker.traverse(:postorder){|t| arr << t.data}
|
68
|
-
arr.must_equal
|
54
|
+
@bin_walker.traverse(:postorder) { |t| arr << t.data }
|
55
|
+
arr.must_equal [9, 11, 5, 12, 14, 8, 2]
|
69
56
|
end
|
70
57
|
|
71
|
-
it
|
72
|
-
@bin_walker.traverse(:inorder).must_equal [9,5,11,2,12,8,14]
|
73
|
-
|
74
|
-
arr = []
|
75
|
-
@bin_walker.traverse(:inorder){|t| arr << t.data}
|
76
|
-
arr.must_equal [9,5,11,2,12,8,14]
|
77
|
-
end
|
78
|
-
|
79
|
-
it "#summarize should transform tree." do
|
80
|
-
@bin_walker.summarize(:bottomup).to_a.must_equal [61,25,34,9,11,12,14]
|
81
|
-
end
|
58
|
+
it 'should traverse in inorder.' do
|
59
|
+
@bin_walker.traverse(:inorder).must_equal [9, 5, 11, 2, 12, 8, 14]
|
82
60
|
|
83
|
-
|
84
|
-
@bin_walker.
|
61
|
+
arr = []
|
62
|
+
@bin_walker.traverse(:inorder) { |t| arr << t.data }
|
63
|
+
arr.must_equal [9, 5, 11, 2, 12, 8, 14]
|
85
64
|
end
|
86
|
-
|
87
65
|
end
|
88
66
|
end
|
89
|
-
|
90
|
-
|
91
|
-
|
data/test/test_tri_matrix.rb
CHANGED
@@ -1,22 +1,17 @@
|
|
1
1
|
require 'help'
|
2
2
|
|
3
3
|
describe TriMatrix do
|
4
|
-
|
5
4
|
before do
|
6
5
|
@tri_matrix = TriMatrix.new
|
7
|
-
@tri_matrix[0,1] = true
|
8
|
-
@tri_matrix[0,2] = true
|
6
|
+
@tri_matrix[0, 1] = true
|
7
|
+
@tri_matrix[0, 2] = true
|
9
8
|
end
|
10
9
|
|
11
|
-
|
12
|
-
|
13
|
-
@tri_matrix[0,1].must_be_same_as @tri_matrix[1,0]
|
10
|
+
it '[x,y] should be same as [y,x]' do
|
11
|
+
@tri_matrix[0, 1].must_be_same_as @tri_matrix[1, 0]
|
14
12
|
end
|
15
13
|
|
16
|
-
it
|
17
|
-
@tri_matrix.to_a.must_equal [0,true,0,true]
|
14
|
+
it 'should store elements in array' do
|
15
|
+
@tri_matrix.to_a.must_equal [0, true, 0, true]
|
18
16
|
end
|
19
|
-
|
20
17
|
end
|
21
|
-
|
22
|
-
|
data/test/test_trie.rb
CHANGED
@@ -1,32 +1,74 @@
|
|
1
1
|
require 'help'
|
2
2
|
|
3
3
|
describe Trie do
|
4
|
-
|
5
4
|
before do
|
6
5
|
@trie = Trie.new
|
7
6
|
@dict = Trie.new
|
8
|
-
@dict.insert(
|
7
|
+
@dict.insert('hello')
|
8
|
+
end
|
9
|
+
|
10
|
+
it '#insert should add new string to trie.' do
|
11
|
+
@trie.insert('thing')
|
12
|
+
assert @trie.find('thing')
|
13
|
+
|
14
|
+
@trie.insert('think')
|
15
|
+
assert @trie.find('thing')
|
16
|
+
|
17
|
+
@trie.insert('math')
|
18
|
+
assert @trie.find('math')
|
9
19
|
end
|
10
20
|
|
11
|
-
it
|
12
|
-
@trie
|
13
|
-
|
14
|
-
|
15
|
-
@trie.insert("think")
|
16
|
-
assert @trie.find("thing")
|
17
|
-
|
18
|
-
@trie.insert("math")
|
19
|
-
assert @trie.find("math")
|
20
|
-
|
21
|
+
it 'has hash like accessors' do
|
22
|
+
@trie['thing'] = 'one'
|
23
|
+
assert_equal @trie['thing'], 'one'
|
21
24
|
end
|
22
25
|
|
23
|
-
it
|
24
|
-
@dict.find(
|
26
|
+
it '#find should not find not added word.' do
|
27
|
+
@dict.find('blah').must_be_nil
|
25
28
|
end
|
26
29
|
|
27
|
-
it
|
28
|
-
|
29
|
-
|
30
|
+
it '#delete removes word from tree' do
|
31
|
+
@dict.insert('he')
|
32
|
+
@dict.insert('help')
|
33
|
+
@dict.delete('hello')
|
34
|
+
refute @dict.find('hello')
|
35
|
+
refute @dict.find('hellp')
|
36
|
+
refute @dict.find('hel')
|
37
|
+
assert @dict.find('he')
|
38
|
+
assert @dict.find('help')
|
30
39
|
end
|
31
40
|
|
41
|
+
it '#each iterates through trie' do
|
42
|
+
@dict.insert('he')
|
43
|
+
@dict.insert('help')
|
44
|
+
assert_equal @dict.map { |n| n }, %w(he hello help)
|
45
|
+
assert_equal @dict.map { |k, v| [k, v] }, [['he', true], ['hello', true], ['help', true]]
|
46
|
+
end
|
47
|
+
|
48
|
+
it '#with_prefix returns words with matching prefix' do
|
49
|
+
@dict.insert('help')
|
50
|
+
@dict.insert('him')
|
51
|
+
assert_equal @dict.with_prefix('he'), %w(hello help)
|
52
|
+
|
53
|
+
arr = []
|
54
|
+
@dict.with_prefix('he') { |n| arr << n }
|
55
|
+
assert_equal arr, %w(hello help)
|
56
|
+
|
57
|
+
assert_equal @dict.with_prefix('yeti'), []
|
58
|
+
end
|
59
|
+
|
60
|
+
it '#to_h converts tree to Hash' do
|
61
|
+
@dict.to_h.must_equal 'hello' => true
|
62
|
+
end
|
63
|
+
|
64
|
+
it '#alphabet= sets Trie alphabet' do
|
65
|
+
@trie = Trie.new
|
66
|
+
@trie.alphabet = %w(a b c d)
|
67
|
+
proc { @trie.insert('thing') }.must_raise ArgumentError
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'should raise error if character is not in trie alphabet.' do
|
71
|
+
proc { @dict.find('m%$r') }.must_raise ArgumentError
|
72
|
+
proc { @dict.insert('m%$r') }.must_raise ArgumentError
|
73
|
+
end
|
32
74
|
end
|