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,20 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "ds/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "ds"
7
+ s.version = DS::VERSION
8
+ s.authors = ["knife"]
9
+ s.email = ["satre@o2.pl"]
10
+ s.homepage = ""
11
+ s.summary = %q{Some common data structures.}
12
+ s.description = %q{Data structures (lists,stacks, trees, heaps, graphs..) in pure Ruby.}
13
+
14
+ s.rubyforge_project = "ds"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+ end
@@ -0,0 +1,38 @@
1
+ require "ds/version"
2
+
3
+ require "ext/ext"
4
+
5
+ require "ds/matrixes/expandable_array"
6
+ require "ds/matrixes/array_2d"
7
+ require "ds/matrixes/tri_matrix"
8
+
9
+ require "ds/graphs/edge"
10
+ require "ds/graphs/graph_as_list"
11
+ require "ds/graphs/graph_as_matrix"
12
+ require "ds/graphs/graph_as_tri_matrix"
13
+ require "ds/graphs/graph"
14
+ require "ds/graphs/digraph"
15
+
16
+ require "ds/trees/tree"
17
+ require "ds/trees/tree_walker"
18
+ require "ds/trees/binary_tree"
19
+ require "ds/trees/binary_search_tree"
20
+ require "ds/trees/complete_binary_tree"
21
+ require "ds/trees/binary_heap"
22
+
23
+ require "ds/lists/list_element"
24
+ require "ds/lists/list"
25
+ require "ds/lists/cyclic_list"
26
+ require "ds/lists/ring"
27
+
28
+ require "ds/stacks/stack"
29
+ require "ds/queues/queue"
30
+
31
+
32
+
33
+
34
+
35
+
36
+
37
+
38
+
@@ -0,0 +1,20 @@
1
+ module DS
2
+ class Digraph < Graph
3
+
4
+ def self.create(args)
5
+ new(args,:matrix)
6
+ end
7
+
8
+
9
+ #Returns number of incoming edges to given vertex.
10
+ def in_degree x
11
+ @g.degree x, :in
12
+ end
13
+
14
+ #Returns number of outcoming edges to given vertex.
15
+ def out_degree x
16
+ @g.degree x, :out
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,15 @@
1
+ module DS
2
+ class Edge
3
+
4
+ attr_accessor :from, :to, :weight
5
+
6
+ #Create new edge.
7
+ def initialize(from,to,weight=1)
8
+ @from = from
9
+ @to = to
10
+ @weight = weight
11
+ end
12
+
13
+ end
14
+ end
15
+
@@ -0,0 +1,107 @@
1
+ module DS
2
+ class Graph
3
+
4
+ Infinity = 1 << 64
5
+
6
+ #Create new graph from array of edges. Second parameter determines
7
+ #graph internal implementation: :list (Adjency List), :tri_matrix (Triangular
8
+ #Matrix), :matrix (Matrix).
9
+ def initialize(edges,store = :list)
10
+ case store
11
+ when :matrix
12
+ @g = GraphAsMatrix.new(edges)
13
+ when :tri_matrix
14
+ @g = GraphAsTriMatrix.new(edges)
15
+ else
16
+ @g = GraphAsList.new(edges)
17
+ end
18
+ end
19
+
20
+ #Create new graph from array of edges. Internally graph will be represented
21
+ #by Triangular Matrix.
22
+ def self.create(edges)
23
+ new(edges,:tri_matrix)
24
+ end
25
+
26
+ def add(x,y)
27
+ @g.add(x,y)
28
+ end
29
+
30
+ def remove(x,y)
31
+ @g.remove(x,y)
32
+ end
33
+
34
+ def each_vertex &block
35
+ @g.each_vertex &block
36
+ end
37
+
38
+ def each_edge &block
39
+ @g.each_edge &block
40
+ end
41
+
42
+ def neighbors v
43
+ @g.neighbors v
44
+ end
45
+
46
+ def bfs s
47
+ colors = {}
48
+ parents = {}
49
+ res = []
50
+ d = {}
51
+ q = Queue.new
52
+
53
+ @g.each_vertex do |v|
54
+ colors[v] = :white
55
+ parents[v] = nil
56
+ d[v] = Infinity
57
+ end
58
+
59
+ colors[s] = :white
60
+ parents[s] = nil
61
+ d[s] = 0
62
+
63
+ q.enqueue s
64
+
65
+ while !q.empty?
66
+ u = q.dequeue
67
+ @g.neighbors(u).each do |v|
68
+ if colors[v] === :white
69
+ colors[v] = :grey
70
+ d[v] = d[u] + 1
71
+ parents[v] = u
72
+ q.enqueue v
73
+ end
74
+ end
75
+ colors[u] = :black
76
+ res << u
77
+ end
78
+ res
79
+ end
80
+
81
+ def add_edges(edges)
82
+ @g.add_edges(edges)
83
+ end
84
+
85
+ #Returns vertex degree. Second parameter determines direction - :in incoming
86
+ #edges, :out - outcoming edges, :all - incoming and outcoming edges.
87
+ def degree x
88
+ @g.degree x
89
+ end
90
+
91
+ def edge? x,y
92
+ @g.edge? x,y
93
+ end
94
+
95
+ def get_edge x, y
96
+ @g.get_edge x,y
97
+ end
98
+
99
+ def vertex_size
100
+ @g.vertex_size
101
+ end
102
+
103
+ def edge_size
104
+ @g.vmax+1
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,48 @@
1
+ module DS
2
+ class GraphAsList
3
+
4
+ def initialize
5
+ @store = {} # the graph // {node => { edge1 => weight, edge2 => weight}, node2 => ...
6
+ @nodes = Array.new
7
+ @INFINITY = 1 << 64
8
+ end
9
+
10
+ def add_edge(x,y,w=nil) # s= source, t= target, w= weight
11
+ if (not @store.has_key?(x))
12
+ @store[x] = {y=>w}
13
+ else
14
+ @store[x][y] = w
15
+ end
16
+
17
+ # Begin code for non directed graph (inserts the other edge too)
18
+
19
+ if (not @store.has_key?(y))
20
+ @store[y] = {x=>w}
21
+ else
22
+ @store[y][x] = w
23
+ end
24
+
25
+ # End code for non directed graph (ie. deleteme if you want it directed)
26
+
27
+ if (not @nodes.include?(x))
28
+ @nodes << x
29
+ end
30
+ if (not @nodes.include?(y))
31
+ @nodes << y
32
+ end
33
+ end
34
+
35
+ def add_edges(edges)
36
+ for e in edges
37
+ add(e.from,e.to)
38
+ end
39
+ end
40
+
41
+ def each_vertex
42
+ @adj_matrix.keys.each do |vertex|
43
+ yield vertex
44
+ end
45
+ end
46
+
47
+ end
48
+ end
@@ -0,0 +1,114 @@
1
+ module DS
2
+ class GraphAsMatrix
3
+
4
+ def initialize(edges)
5
+ @store = Array2D.new
6
+ @max = 0
7
+
8
+ @v = 0 #vertex count
9
+
10
+ @map = [] #maps objects to matrix indexes.
11
+
12
+ add_edges(edges)
13
+ end
14
+
15
+ #Checks if two elements are connected.
16
+ def edge? x,y
17
+ v1 = @map.index(x)
18
+ v2 = @map.index(y)
19
+ @store[v1,v2] > 0
20
+ end
21
+
22
+ #Adds new edges to graph.
23
+ def add_edges(edges)
24
+ for e in edges
25
+ x = @map.push_uniq e.from
26
+ y = @map.push_uniq e.to
27
+
28
+ @store[x,y] = e.weight
29
+ @max = [@max, x, y].max
30
+ @v = @v + 1
31
+ end
32
+ end
33
+
34
+ #Returns all neighbors for given vertex.
35
+ def neighbors(v)
36
+ n = []
37
+ v = @map.index(v)
38
+ 0.upto @max do |i|
39
+ n << @map[i] if @store[v,i] > 0
40
+ end
41
+ n
42
+ end
43
+
44
+ #Removes conection between vertex x and y.
45
+ def remove(x,y)
46
+ v1 = @map.index(x)
47
+ v2 = @map.index(y)
48
+
49
+ @store[v1,v2] = 0
50
+ if (degree @map[@max]) == 0
51
+ @max -= 1
52
+ end
53
+ @v -= 1
54
+ end
55
+
56
+ #Returns Edge(x,y) if exist.
57
+ def get_edge x,y
58
+ s = @map.index x
59
+ t = @map.index y
60
+ if @store[s,t] > 0
61
+ Edge.new(@map[s], @map[t], @store[s,t])
62
+ else
63
+ nil
64
+ end
65
+ end
66
+
67
+ def vmax
68
+ @max
69
+ end
70
+
71
+ #Returns vertex counter.
72
+ def vertex_size
73
+ @v
74
+ end
75
+
76
+
77
+ #Returns vertex degree. Second parameter determines direction - :in incoming
78
+ #edges, :out - outcoming edges, :all - incoming and outcoming edges.
79
+ def degree(x,direction=:all)
80
+ x = @map.index(x)
81
+ sum_in = 0
82
+ sum_out = 0
83
+ 0.upto @max do |i|
84
+ sum_in += 1 if @store[i,x] and @store[i,x] > 0
85
+ sum_out += 1 if @store[x,i] and @store[x,i] > 0
86
+ end
87
+
88
+ case direction
89
+ when :all
90
+ sum_in+sum_out
91
+ when :in
92
+ sum_in
93
+ when :out
94
+ sum_out
95
+ end
96
+ end
97
+
98
+
99
+ #Vertex iterator
100
+ def each_vertex
101
+ (0..@max).each {|v| yield @map[v]}
102
+ end
103
+
104
+ #Edge iterator
105
+ def each_edge
106
+ for v0 in 0..@max
107
+ for v1 in 0..v0-1
108
+ yield Edge.new(@map[v0],@map[v1],@store[v0,v1]) if @store[v0,v1] > 0
109
+ end
110
+ end
111
+ end
112
+
113
+ end
114
+ end
@@ -0,0 +1,25 @@
1
+ module DS
2
+ class GraphAsTriMatrix < GraphAsMatrix
3
+
4
+ def initialize(edges)
5
+ @store = TriMatrix.new(0)
6
+ @max = 0
7
+ @map = []
8
+ @v = 0
9
+
10
+ add_edges(edges)
11
+ end
12
+
13
+ #Returns vertex degree.
14
+ def degree(x)
15
+ x = @map.index(x)
16
+ sum = 0
17
+ 0.upto @max do |i|
18
+ sum += @store[x,i] if @store[x,i]
19
+ end
20
+ sum
21
+ end
22
+
23
+ end
24
+ end
25
+
@@ -0,0 +1,21 @@
1
+ module DS
2
+
3
+ #Class represent list with cycle.
4
+ class CyclicList < List
5
+
6
+ #Returns cycle size. If list has no cycles returns 0.
7
+ def cycle_size
8
+ counter = 0
9
+ if start = self.joint
10
+ counter = 1
11
+ elem = joint.next
12
+ while elem != start
13
+ elem = elem.next
14
+ counter += 1
15
+ end
16
+ end
17
+ counter
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,303 @@
1
+ module DS
2
+
3
+ #Implements simple list data structure.
4
+ class List
5
+
6
+ include Enumerable
7
+
8
+ attr_accessor :head, :tail
9
+
10
+ #Creates new list.
11
+ def initialize(x=nil)
12
+ @head = ListElement.new(x)
13
+ @tail = @head
14
+ end
15
+
16
+ #Creates list from array.
17
+ def self.from_array(arr)
18
+ list = new(arr.shift)
19
+ tail = list.head
20
+ arr.each{ |e| tail = tail.append(e) }
21
+ list.tail = tail
22
+ list
23
+ end
24
+
25
+ #Appends new element to list.
26
+ def append(x)
27
+ last_elem = self.tail
28
+ if !empty?
29
+ @tail = last_elem.append(x)
30
+ else
31
+ @head = ListElement.new(x)
32
+ @tail = @head
33
+ end
34
+ end
35
+
36
+ alias :<< :append
37
+
38
+ #Prepends new element to list.
39
+ def prepend(x)
40
+ el = ListElement.new(x)
41
+ el.next = @head
42
+ @head = el
43
+ end
44
+
45
+ #Removes element x from list.
46
+ def remove(x)
47
+ if x == head
48
+ self.head = head.next
49
+ x.next = nil
50
+ else
51
+
52
+ el = head
53
+ while el and el != x
54
+ prev = el
55
+ el = el.next
56
+ end
57
+
58
+ raise "Element not found" unless el
59
+
60
+ prev.next = el.next
61
+ el.next = nil
62
+ end
63
+ x
64
+ end
65
+
66
+ #Removes list head.
67
+ def shift
68
+ remove(head).data
69
+ end
70
+
71
+ #Inserts element x after another element.
72
+ def insert_after(x,rel)
73
+ x = ListElement.new(x)
74
+
75
+ el = head
76
+ while el and el != rel
77
+ el = el.next
78
+ end
79
+
80
+ raise "Element not found" unless el
81
+
82
+ x.next = el.next
83
+ el.next = x
84
+
85
+ if x.tail?
86
+ self.tail = x
87
+ end
88
+ end
89
+
90
+ #Inserts element x before another element.
91
+ def insert_before(x,rel)
92
+ x = ListElement.new(x)
93
+
94
+ #inserting at the beginnig of the list
95
+ if rel == head
96
+ x.next = head
97
+ self.head = x
98
+
99
+ #inserting in the tail of the list
100
+ else
101
+ el = head
102
+ prev = head
103
+ while el and el != rel
104
+ prev = el
105
+ el = el.next
106
+ end
107
+
108
+ if el.nil?
109
+ raise "List element not found"
110
+ else
111
+ prev.next = x
112
+ x.next = el
113
+ end
114
+ end
115
+ end
116
+
117
+
118
+ #Checks if list is empty.
119
+ def empty?
120
+ head.data.nil?
121
+ end
122
+
123
+ #Returns last element of the list.
124
+ def last
125
+ tail.data
126
+ end
127
+
128
+ def first
129
+ head.data
130
+ end
131
+
132
+ #Returns length of the list.
133
+ def length
134
+ count
135
+ end
136
+
137
+ #Checks if list is linked at the end with other list.
138
+ def zip?(other)
139
+ tail.equal? other.tail
140
+ end
141
+
142
+ #Returns joint element if exists, otherwise returns nil.
143
+ def joint
144
+ elem = head
145
+ elem2 = elem.next
146
+
147
+ while elem and elem2
148
+
149
+ #traversing by 1
150
+ elem = elem.next
151
+
152
+ #traversing by 2
153
+ elem2 = elem2.next
154
+ elem2 = elem2.next if elem2
155
+
156
+ if elem2.equal? elem
157
+ return elem
158
+ end
159
+ end
160
+
161
+ nil
162
+ end
163
+
164
+ #Returns true if list has cycle.
165
+ def looped?
166
+ !!joint
167
+ end
168
+
169
+
170
+ #Orderize list by evaluating block. Block should evaluate to one of these
171
+ #values: 1,0,-1 (same as Comparable).
172
+ def orderize
173
+
174
+ zero = List.new
175
+ plus = List.new
176
+ minus = List.new
177
+
178
+ el = self.head
179
+
180
+ while el
181
+ case yield el.data
182
+ when 0
183
+ zero_tail = zero.append(el.data)
184
+ when 1
185
+ plus_tail = plus.append(el.data)
186
+ when -1
187
+ minus_tail = minus.append(el.data)
188
+ end
189
+
190
+ el = el.next
191
+ end
192
+
193
+ minus_tail.next = zero.head
194
+ zero_tail.next = plus.head
195
+ return minus
196
+ end
197
+
198
+
199
+ # Removes elements that exists on the other list.
200
+ def remove!(other)
201
+ a = head
202
+ b = other.head
203
+
204
+ while a and b
205
+
206
+ while a.data < b.data
207
+ prev = a
208
+ a = a.next
209
+ end
210
+
211
+ while b.data < a.data
212
+ b = b.next
213
+ end
214
+
215
+ a = a.next
216
+ prev.next = a
217
+ b = b.next
218
+ end
219
+ self
220
+ end
221
+
222
+ # Merge list with other list.
223
+ def merge(other)
224
+
225
+ a = self.head
226
+ b = other.head
227
+
228
+ if a.data < b.data
229
+ result = List.new(a.data)
230
+ a = a.next
231
+ else
232
+ result = List.new(b.data)
233
+ b = b.next
234
+ end
235
+
236
+ while a and b
237
+ if a.data < b.data
238
+ result.append(a.data)
239
+ a = a.next
240
+ else
241
+ result.append(b.data)
242
+ b = b.next
243
+ end
244
+ end
245
+ if !b
246
+ result.tail.next = a
247
+ result.tail = self.tail
248
+ elsif !a
249
+ result.tail.next = b
250
+ result.tail = other.tail
251
+ end
252
+ result
253
+ end
254
+
255
+ #Reverses list.
256
+ def reverse!
257
+ @tail = self.head
258
+ prev = self.head
259
+ elem = prev.next
260
+ prev.next = nil
261
+ while elem
262
+ nxt = elem.next
263
+ elem.next = prev
264
+ prev = elem
265
+ elem = nxt
266
+ end
267
+
268
+ @head = prev
269
+ self
270
+
271
+ end
272
+
273
+ #Prints list.
274
+ def print
275
+ each { |e| p }
276
+ end
277
+
278
+ #Converts list to array.
279
+ def to_a
280
+ map { |e| e}
281
+ end
282
+
283
+ #Default list iterator.
284
+ def each
285
+ elem = @head
286
+ while elem
287
+ yield elem.data
288
+ elem = elem.next
289
+ end
290
+ end
291
+
292
+ def each_with_index
293
+ elem = @head
294
+ i = 0
295
+ while elem
296
+ yield elem,i
297
+ elem = elem.next
298
+ i = i + 1
299
+ end
300
+ end
301
+
302
+ end
303
+ end