1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Copyright 2009 Jean Privat <jean@pryen.org>
5 # This file is free software, which comes along with NIT. This software is
6 # distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
7 # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
8 # PARTICULAR PURPOSE. You can modify it is you want, provided this header
9 # is kept unaltered, and a notification of the changes is added.
10 # You are allowed to redistribute it and sell it, alone or is a part of
13 # This module define several collection classes.
16 import abstract_collection
21 import hash_collection
24 redef class Sequence[E
]
25 fun subarray
(start
, len
: Int): Array[E
]
27 var a
= new Array[E
].with_capacity
(len
)
28 for i
in [start
.. start
+len
[ do a
.add
(self[i
])
33 # A queue is a FIFO data structure
35 # It's particular kind of collection in which the entities in the collection are kept in order.
36 # and the principal operations on the collection are:
37 # * the addition of entities to the rear terminal position, known as `enqueue`
38 # * the removal of entities from the front terminal position, known as `dequeue`
39 # This makes the queue a First-In-First-Out (FIFO) data structure.
40 # In a FIFO data structure, the first element added to the queue will be the first one to be removed.
41 # This is equivalent to the requirement that once a new element is added,
42 # all elements that were added before have to be removed before the new element can be removed.
46 # Add an item in the queue
47 fun enqueue
(item
: E
) is abstract
49 # Dequeue the next item
50 fun dequeue
: E
is abstract
52 # Show the next item on the queue but do not remove it
53 fun top
: E
is abstract
56 # Circular queue based on an array.
57 # A data structure that uses a single, fixed-size queue as if it were connected end-to-end.
58 class CircularQueue[E
]
61 private var items
: Array[nullable E
]
64 private var icount
= 0
69 items
= new Array[nullable E
].filled_with
(null, size
)
72 # var queue = new CircularQueue[Int](5)
76 # assert queue.length == 3
77 redef fun enqueue
(item
) do
78 assert is_full
: not is_full
80 if tail
== size
- 1 then
88 # var queue = new CircularQueue[Int](5)
91 # assert queue.dequeue == 10
92 # assert queue.dequeue == 20
93 # assert queue.is_empty
95 assert is_empty
: not is_empty
98 if head
== size
- 1 then
104 return e
.as(not null)
107 # var queue = new CircularQueue[Int](5)
110 # assert queue.top == 1
112 # assert queue.top == 2
114 assert is_empty
: not is_empty
118 # var queue = new CircularQueue[Int](5)
120 # assert queue.length == 1
122 # assert queue.length == 2
124 # assert queue.length == 1
126 # assert queue.length == 0
127 redef fun length
do return icount
129 # var queue = new CircularQueue[Int](5)
130 # assert queue.is_empty
132 # assert not queue.is_empty
134 # assert queue.is_empty
135 redef fun is_empty
do return icount
== 0
139 # var queue = new CircularQueue[Int](3)
140 # assert not queue.is_full
144 # assert queue.is_full
146 # assert not queue.is_full
147 fun is_full
: Bool do return icount
== size
149 # var queue = new CircularQueue[Int](3)
153 # var res = new Array[Int]
154 # for e in queue do res.add(e)
155 # assert res == [10, 20, 30]
156 redef fun iterator
do return new CircularQueueIterator[E
](self)
159 private class CircularQueueIterator[E
]
162 var queue
: CircularQueue[E
]
166 init(queue
: CircularQueue[E
]) do
168 self.current
= queue
.head
172 redef fun is_ok
do return iterations
< queue
.length
175 if current
== queue
.size
- 1 then
183 redef fun item
do return queue
.items
[current
]
186 # Stack implemented with an array
187 # A stack is a particular kind of collection
188 # in which the principal operations are:
189 # * the addition of an entity to the collection, known as `push`
190 # * the removal of an entity, known as `pop`
191 # This makes the queue a Last-In-First-Out (LIFO) data structure.
192 # In a LIFO data structure, the last element added to the structure must be the first one
194 # This is equivalent to the requirement that, considered as a linear collection,
195 # the push and pop operations occur only at one end of the structure,
196 # referred to as the top of the stack.
200 # var stack = new Stack[Int]
203 # assert stack.pop == 2
204 # assert stack.pop == 1
208 private var items
= new List[E
]
211 # Is the stack empty?
213 # var stack = new Stack[Int]
214 # assert stack.is_empty
216 # assert not stack.is_empty
218 # assert stack.is_empty
219 redef fun is_empty
do return itop
== 0
221 # Add an item on top of the stack
223 # var stack = new Stack[Int]
226 # assert stack.length == 2
232 # Pop the item on the top of the stack
234 # var stack = new Stack[Int]
237 # assert stack.pop == 2
238 # assert stack.pop == 1
239 # assert stack.is_empty
241 assert empty
: not is_empty
246 # Show the item on the top of the stack but do not remove it
248 # var stack = new Stack[Int]
251 # assert stack.top == 2
253 # assert stack.top == 1
255 assert empty
: not is_empty
256 return items
[itop
- 1]
259 # Number of items contained in the stack
261 # var stack = new Stack[Int]
262 # assert stack.length == 0
264 # assert stack.length == 1
266 # assert stack.length == 2
267 # assert stack.pop == 2
268 # assert stack.length == 1
269 # assert stack.pop == 1
270 # assert stack.length == 0
271 redef fun length
do return itop
273 # Get an iterator over the stack
275 # var stack = new Stack[Int]
279 # for item in stack do sum += item
281 redef fun iterator
do return items
.iterator
284 # A heap is a data structure that satisfies the heap property:
285 # If A is a parent node of B then the key of node A is ordered with respect
286 # to the key of node B with the same ordering applying across the heap.
287 # Either the keys of parent nodes are always greater than or equal to those of the children
288 # and the highest key is in the root node (this kind of heap is called max heap)
289 # or the keys of parent nodes are less than or equal to those of the children
290 # and the lowest key is in the root node (min heap).
292 # Heaps are crucial in several efficient graph algorithms such as Dijkstra's algorithm,
293 # and in the sorting algorithm heapsort.
297 # Get the minimum element of the heap
298 fun min
: E
is abstract
300 # Remove and return the minimum
301 fun pop
: E
is abstract
303 # Add an element in the heap
304 fun add
(e
: E
) is abstract
306 # Update the heap structure
307 fun build_heap
is abstract
310 # Heap implemented over an array
314 private var items
: Array[E
]
315 private var size
: Int = -1
316 private var comparator
: Comparator[E
]
318 init(comparator
: Comparator[E
]) do
319 self.comparator
= comparator
323 # Init the heap using an existing array
324 init from
(comparator
: Comparator[E
], array
: Array[E
]) do
325 self.comparator
= comparator
326 size
= array
.length
- 1
331 redef fun build_heap
do
339 private fun heapify
(from
: Int) do
343 if l
<= size
and comparator
.compare
(items
[l
], items
[largest
]) > 0 then
348 if r
<= size
and comparator
.compare
(items
[r
], items
[largest
]) > 0 then
351 if largest
!= from
then
352 items
.swap_at
(from
, largest
)
357 private fun swap_at
(a
, b
: Int) do
363 redef fun length
do return size
+ 1
364 redef fun is_empty
do return length
== 0
365 redef fun iterator
do return items
.iterator
368 assert not_empty
: not is_empty
373 assert not_empty
: not is_empty
388 var res
= new Array[E
]
389 for i
in [0..size
] do res
.add items
[i
]
394 # Priority Queue implemented over an ArrayHeap
395 # A priority queue is an abstract data type which is like a regular queue,
396 # but where additionally each element has a "priority" associated with it.
397 # In a priority queue, an element with high priority is served before an element with low priority.
398 # If two elements have the same priority, they are served according to their order in the queue.
402 # var comparator = new DefaultComparator[Int]
403 # var queue = new PriorityQueue[Int](comparator)
407 # assert not queue.is_empty
408 # assert queue.dequeue == 30
409 # assert queue.dequeue == 11
410 # assert queue.dequeue == 9
412 # Init priority queue from array:
414 # var queue2 = new PriorityQueue[Int].from(comparator, [2, 4, 1, 5, 3, 12, 0])
415 # assert queue2.length == 7
416 # assert queue2.top == 12
417 class PriorityQueue[E
]
422 init(comparator
: Comparator[E
]) do
423 heap
= new ArrayHeap[E
](comparator
)
426 init from
(comparator
: Comparator[E
], items
: Collection[E
]) do
427 heap
= new ArrayHeap[E
].from
(comparator
, items
.to_a
)
430 # var comparator = new DefaultComparator[Int]
431 # var queue = new PriorityQueue[Int].from(comparator, [2, 4, 1, 5, 3, 12, 0])
432 # assert queue.dequeue == 12
433 # assert queue.dequeue == 5
434 # assert queue.dequeue == 4
435 # assert queue.length == 4
436 redef fun dequeue
do return heap
.pop
438 # var comparator = new DefaultComparator[Int]
439 # var queue = new PriorityQueue[Int](comparator)
443 # assert queue.dequeue == 32
444 # assert queue.dequeue == 18
445 # assert queue.dequeue == 12
446 redef fun enqueue
(e
) do heap
.add e
448 # var comparator = new DefaultComparator[Int]
449 # var queue = new PriorityQueue[Int].from(comparator, [2, 4, 1, 5, 3, 12, 0])
450 # assert queue.top == 12
452 # assert queue.top == 5
453 redef fun top
do return heap
.min
455 redef fun length
do return heap
.length
456 redef fun iterator
do return heap
.iterator