1 Queues
Following queue structures implement and provide the functions empty?, enqueue, head, tail, queue and queue->list. All the queue structures are polymorphic and have the type (Queue A).
1.1 Banker’s Queue
(require "bankers-queue.ss") |
A Queue is nothing but a FIFO data structure. A Banker’s Queue is a amortized queue obtained using Bankers method. It provides a amortized running time of O(1) for head, tail and enqueue operations. To obtain this amortized running time, the data structure uses the techniques, lazy evaluation and memoization. Banker’s Queue internally uses Streams for lazy evaluation. For Streams, see Streams
(queue a ...) → (Queue A) |
a : A |
Example: |
> (queue 1 2 3 4 5 6) |
- : (Queue Positive-Fixnum) |
#<Queue> |
In the above example, the queue obtained will have 1 as its head element.
empty : (Queue Nothing) |
(empty? que) → Boolean |
que : (Queue A) |
Examples: |
> (empty? (queue 1 2 3 4 5 6)) |
- : Boolean |
#f |
> (empty? empty) |
- : Boolean |
#t |
(enqueue a que) → (Queue A) |
a : A |
que : (Queue A) |
In the above example, (enqueue 10 (queue 4 5 6)) enqueues 10 to the end of the queue and returns (queue 4 5 6 10).
(head que) → A |
que : (Queue A) |
Examples: |
> (head (queue 10 4 3 12)) |
- : Positive-Fixnum |
10 |
> (head empty) |
head: given queue is empty |
(tail que) → (Queue A) |
que : (Queue A) |
Examples: |
> (tail (queue 4 5 6)) |
- : (Queue Positive-Fixnum) |
#<Queue> |
> (tail empty) |
tail: given queue is empty |
In the above example, (tail (queue 4 5 6)), returns (queue 5 6).
(queue->list que) → (Queue A) |
que : (Queue A) |
Examples: |
> (queue->list (queue 10 2 34 4 15 6)) |
- : (Listof Positive-Fixnum) |
'(10 2 34 4 15 6) |
> (queue->list empty) |
- : (Listof Nothing) |
'() |
(map func que1 que2 ...) → (Queue A) |
func : (A B ... B -> C) |
que1 : (Queue A) |
que2 : (Queue B) |
Examples: |
> (queue->list (map add1 (queue 1 2 3 4 5 6))) |
- : (Listof Exact-Positive-Integer) |
'(2 3 4 5 6 7) |
> (queue->list (map * (queue 1 2 3 4 5 6) (queue 1 2 3 4 5 6))) |
- : (Listof Exact-Positive-Integer) |
'(1 4 9 16 25 36) |
(fold func init que1 que2 ...) → C |
func : (C A B ... B -> C) |
init : C |
que1 : (Queue A) |
que2 : (Queue B) |
fold currently does not produce correct results when the given function is non-commutative.
Examples: |
> (fold + 0 (queue 1 2 3 4 5 6)) |
- : Exact-Nonnegative-Integer |
21 |
> (fold * 1 (queue 1 2 3 4 5 6) (queue 1 2 3 4 5 6)) |
- : Exact-Positive-Integer |
518400 |
(filter func que) → (Queue A) |
func : (A -> Boolean) |
que : (Queue A) |
Examples: |
> (define que (queue 1 2 3 4 5 6)) |
> (queue->list (filter (λ: ([x : Integer]) (> x 5)) que)) |
- : (Listof Positive-Fixnum) |
'(6) |
> (queue->list (filter (λ: ([x : Integer]) (< x 5)) que)) |
- : (Listof Positive-Fixnum) |
'(1 2 3 4) |
> (queue->list (filter (λ: ([x : Integer]) (<= x 5)) que)) |
- : (Listof Positive-Fixnum) |
'(1 2 3 4 5) |
(remove func que) → (Queue A) |
func : (A -> Boolean) |
que : (Queue A) |
Examples: | ||
| ||
- : (Listof Positive-Fixnum) | ||
'(1 2 3 4 5) | ||
| ||
- : (Listof Positive-Fixnum) | ||
'(5 6) | ||
| ||
- : (Listof Positive-Fixnum) | ||
'(6) |
1.2 Physicist’s Queue
(require "physicists-queue.ss") |
A Queue is nothing but a FIFO data structure. A Physicist’s queue ia a Amortized queues obtained by Physicist’s method. Provides a amortized running time of O(1) for head, tail and enqueue operations. Physicists’s Queue uses lazy evaluation and memoization to get this amortized running time.
(queue a ...) → (Queue A) |
a : A |
Example: |
> (queue 1 2 3 4 5 6) |
- : (Queue Positive-Fixnum) |
#<Queue> |
In the above example, the queue obtained will have 1 as its head element
empty : (Queue Nothing) |
(empty? que) → Boolean |
que : (Queue A) |
Examples: |
> (empty? (queue 1 2 3 4 5 6)) |
- : Boolean |
#f |
> (empty? empty) |
- : Boolean |
#t |
(enqueue a que) → (Queue A) |
a : A |
que : (Queue A) |
In the above example, enqueue adds the element 10 to (queue 1 2 3 4 5 6) and returns (queue 1 2 3 4 5 6 10).
(head que) → A |
que : (Queue A) |
Examples: |
> (head (queue 1 2 3 4 5 6)) |
- : Positive-Fixnum |
1 |
> (head empty) |
head: given queue is empty |
(tail que) → (Queue A) |
que : (Queue A) |
Examples: |
> (tail (queue 1 2 3 4 5 6)) |
- : (Queue Positive-Fixnum) |
#<Queue> |
> (tail empty) |
tail: given queue is empty |
In the above example, (tail (queue 1 2 3 4 5 6)), returns (queue 2 3 4 5 6).
(queue->list que) → (Queue A) |
que : (Queue A) |
Examples: |
> (queue->list (queue 10 2 34 4 15 6)) |
- : (Listof Positive-Fixnum) |
'(10 2 34 4 15 6) |
> (queue->list empty) |
- : (Listof Nothing) |
'() |
(map func que1 que2 ...) → (Queue A) |
func : (A B ... B -> C) |
que1 : (Queue A) |
que2 : (Queue B) |
Examples: |
> (queue->list (map add1 (queue 1 2 3 4 5 6))) |
- : (Listof Exact-Positive-Integer) |
'(2 3 4 5 6 7) |
> (queue->list (map * (queue 1 2 3 4 5 6) (queue 1 2 3 4 5 6))) |
- : (Listof Exact-Positive-Integer) |
'(1 4 9 16 25 36) |
(fold func init que1 que2 ...) → C |
func : (C A B ... B -> C) |
init : C |
que1 : (Queue A) |
que2 : (Queue B) |
fold currently does not produce correct results when the given function is non-commutative.
Examples: |
> (fold + 0 (queue 1 2 3 4 5 6)) |
- : Exact-Nonnegative-Integer |
21 |
> (fold * 1 (queue 1 2 3 4 5 6) (queue 1 2 3 4 5 6)) |
- : Exact-Positive-Integer |
518400 |
(filter func que) → (Queue A) |
func : (A -> Boolean) |
que : (Queue A) |
Examples: |
> (define que (queue 1 2 3 4 5 6)) |
> (queue->list (filter (λ: ([x : Integer]) (> x 5)) que)) |
- : (Listof Positive-Fixnum) |
'(6) |
> (queue->list (filter (λ: ([x : Integer]) (< x 5)) que)) |
- : (Listof Positive-Fixnum) |
'(1 2 3 4) |
> (queue->list (filter (λ: ([x : Integer]) (<= x 5)) que)) |
- : (Listof Positive-Fixnum) |
'(1 2 3 4 5) |
(remove func que) → (Queue A) |
func : (A -> Boolean) |
que : (Queue A) |
Examples: | ||
| ||
- : (Listof Positive-Fixnum) | ||
'(1 2 3 4 5) | ||
| ||
- : (Listof Positive-Fixnum) | ||
'(5 6) | ||
| ||
- : (Listof Positive-Fixnum) | ||
'(6) |
1.3 Implicit Queue
(require "implicitqueue.ss") |
Queues obtained by applying the technique called Implicit Recursive Slowdown. Provides a amortized running time of O(1) for the operations head, tail and enqueue. Implicit Recursive Slowdown combines laziness and technique called Recursive Slow-Down developed by Kaplan and Tarjan in their paper Persistant Lists with Catenation via Recursive Slow-Down.
(queue a ...) → (Queue A) |
a : A |
Example: |
> (queue 1 2 3 4 5 6) |
- : (U (Shallow Positive-Fixnum) (Deep Positive-Fixnum)) |
#<Deep> |
In the above example, the queue obtained will have 1 as its head element.
empty : (Queue Nothing) |
(empty? que) → Boolean |
que : (Queue A) |
Examples: |
> (empty? (queue 1 2 3 4 5 6)) |
- : Boolean |
#f |
> (empty? empty) |
- : Boolean |
#t |
(enqueue a que) → (Queue A) |
a : A |
que : (Queue A) |
Example: |
> (enqueue 10 (queue 1 2 3 4 5 6)) |
- : (U (Shallow Positive-Fixnum) (Deep Positive-Fixnum)) |
#<Deep> |
In the above example, enqueue adds the element 10 to of (queue 1 2 3 4 5 6) and returns (queue 1 2 3 4 5 6 10).
(head que) → A |
que : (Queue A) |
Examples: |
> (head (queue 1 2 3 4 5 6)) |
- : Positive-Fixnum |
1 |
> (head empty) |
head: given queue is empty |
(tail que) → (Queue A) |
que : (Queue A) |
Examples: |
> (tail (queue 1 2 3 4 5 6)) |
- : (U (Shallow Positive-Fixnum) (Deep Positive-Fixnum)) |
#<Deep> |
> (tail empty) |
tail: given queue is empty |
(queue->list que) → (Queue A) |
que : (Queue A) |
Examples: |
> (queue->list (queue 10 2 34 4 15 6)) |
- : (Listof Positive-Fixnum) |
'(10 2 34 4 15 6) |
> (queue->list empty) |
- : (Listof Nothing) |
'() |
(map func que1 que2 ...) → (Queue A) |
func : (A B ... B -> C) |
que1 : (Queue A) |
que2 : (Queue B) |
Examples: |
> (queue->list (map add1 (queue 1 2 3 4 5 6))) |
- : (Listof Exact-Positive-Integer) |
'(2 3 4 5 6 7) |
> (queue->list (map * (queue 1 2 3 4 5 6) (queue 1 2 3 4 5 6))) |
- : (Listof Exact-Positive-Integer) |
'(1 4 9 16 25 36) |
(fold func init que1 que2 ...) → C |
func : (C A B ... B -> C) |
init : C |
que1 : (Queue A) |
que2 : (Queue B) |
fold currently does not produce correct results when the given function is non-commutative.
Examples: |
> (fold + 0 (queue 1 2 3 4 5 6)) |
- : Exact-Nonnegative-Integer |
21 |
> (fold * 1 (queue 1 2 3 4 5 6) (queue 1 2 3 4 5 6)) |
- : Exact-Positive-Integer |
518400 |
(filter func que) → (Queue A) |
func : (A -> Boolean) |
que : (Queue A) |
Examples: |
> (define que (queue 1 2 3 4 5 6)) |
> (queue->list (filter (λ: ([x : Integer]) (> x 5)) que)) |
- : (Listof Positive-Fixnum) |
'(6) |
> (queue->list (filter (λ: ([x : Integer]) (< x 5)) que)) |
- : (Listof Positive-Fixnum) |
'(1 2 3 4) |
> (queue->list (filter (λ: ([x : Integer]) (<= x 5)) que)) |
- : (Listof Positive-Fixnum) |
'(1 2 3 4 5) |
(remove func que) → (Queue A) |
func : (A -> Boolean) |
que : (Queue A) |
Examples: | ||
| ||
- : (Listof Positive-Fixnum) | ||
'(1 2 3 4 5) | ||
| ||
- : (Listof Positive-Fixnum) | ||
'(5 6) | ||
| ||
- : (Listof Positive-Fixnum) | ||
'(6) |
1.4 Bootstraped Queue
(require "bootstrapedqueue.ss") |
Bootstrapped Queue use a structural bootstrapping technique called Structural Decomposition. The data structure gives a worst case running time of O(1) for the operation head and O(log*(n)) for tail and enqueue. Internally uses Real-Time Queue.
(queue a ...) → (Queue A) |
a : A |
Example: |
> (queue 1 2 3 4 5 6) |
- : (U EmptyBSQueue (IntQue Positive-Fixnum)) |
#<IntQue> |
In the above example, the queue obtained will have 1 as its first element.
empty : (Queue Nothing) |
(empty? que) → Boolean |
que : (Queue A) |
Examples: |
> (empty? (queue 1 2 3 4 5 6)) |
- : Boolean |
#f |
> (empty? empty) |
- : Boolean |
#t |
(enqueue a que) → (Queue A) |
a : A |
que : (Queue A) |
In the above example, (enqueue 10 (queue 1 2 3 4 5 6)) adds the 10 to the queue (queue 1 2 3 4 5 6). 10 as its last element.
(head que) → A |
que : (Queue A) |
Examples: |
> (head (queue 1 2 3 4 5 6)) |
- : Positive-Fixnum |
1 |
> (head empty) |
head: given queue is empty |
(tail que) → (Queue A) |
que : (Queue A) |
Examples: |
> (tail (queue 1 2 3 4 5 6)) |
- : (U EmptyBSQueue (IntQue Positive-Fixnum)) |
#<IntQue> |
> (tail empty) |
tail: given queue is empty |
In the above example, (tail (queue 1 2 3 4 5 6)), removes the head of the given queue returns (queue 2 3 4 5 6).
(queue->list que) → (Queue A) |
que : (Queue A) |
Examples: |
> (queue->list (queue 10 2 34 4 15 6)) |
- : (Listof Positive-Fixnum) |
'(10 2 34 4 15 6) |
> (queue->list empty) |
- : (Listof Nothing) |
'() |
(map func que1 que2 ...) → (Queue A) |
func : (A B ... B -> C) |
que1 : (Queue A) |
que2 : (Queue B) |
Examples: |
> (queue->list (map add1 (queue 1 2 3 4 5 6))) |
- : (Listof Exact-Positive-Integer) |
'(2 3 4 5 6 7) |
> (queue->list (map * (queue 1 2 3 4 5 6) (queue 1 2 3 4 5 6))) |
- : (Listof Exact-Positive-Integer) |
'(1 4 9 16 25 36) |
(fold func init que1 que2 ...) → C |
func : (C A B ... B -> C) |
init : C |
que1 : (Queue A) |
que2 : (Queue B) |
fold currently does not produce correct results when the given function is non-commutative.
Examples: |
> (fold + 0 (queue 1 2 3 4 5 6)) |
- : Exact-Nonnegative-Integer |
21 |
> (fold * 1 (queue 1 2 3 4 5 6) (queue 1 2 3 4 5 6)) |
- : Exact-Positive-Integer |
518400 |
(filter func que) → (Queue A) |
func : (A -> Boolean) |
que : (Queue A) |
Examples: |
> (define que (queue 1 2 3 4 5 6)) |
> (queue->list (filter (λ: ([x : Integer]) (> x 5)) que)) |
- : (Listof Positive-Fixnum) |
'(6) |
> (queue->list (filter (λ: ([x : Integer]) (< x 5)) que)) |
- : (Listof Positive-Fixnum) |
'(1 2 3 4) |
> (queue->list (filter (λ: ([x : Integer]) (<= x 5)) que)) |
- : (Listof Positive-Fixnum) |
'(1 2 3 4 5) |
(remove func que) → (Queue A) |
func : (A -> Boolean) |
que : (Queue A) |
Examples: | ||
| ||
- : (Listof Positive-Fixnum) | ||
'(1 2 3 4 5) | ||
| ||
- : (Listof Positive-Fixnum) | ||
'(5 6) | ||
| ||
- : (Listof Positive-Fixnum) | ||
'(6) |
1.5 Real-Time Queue
(require "realtimequeue.ss") |
Real-Time Queues eliminate the amortization by employing laziness and a technique called Scheduling. The data structure gives a worst case running time of O(1) for the operations head, tail and enqueue.
(queue a ...) → (Queue A) |
a : A |
Example: |
> (queue 1 2 3 4 5 6) |
- : (Queue Positive-Fixnum) |
#<Queue> |
In the above example, the queue obtained will have 1 as its first element.
empty : (Queue Nothing) |
(empty? que) → Boolean |
que : (Queue A) |
Examples: |
> (empty? (queue 1 2 3 4 5 6)) |
- : Boolean |
#f |
> (empty? empty) |
- : Boolean |
#t |
(enqueue a que) → (Queue A) |
a : A |
que : (Queue A) |
In the above example, (enqueue 10 que) adds 10 to the end of (queue 1 2 3 4 5 6) and returns (queue 1 2 3 4 5 6 10).
(head que) → A |
que : (Queue A) |
Examples: |
> (head (queue 1 2 3 4 5 6)) |
- : Positive-Fixnum |
1 |
> (head empty) |
head: given queue is empty |
(tail que) → (Queue A) |
que : (Queue A) |
Examples: |
> (tail (queue 1 2 3 4 5 6)) |
- : (Queue Positive-Fixnum) |
#<Queue> |
> (tail empty) |
tail: given queue is empty |
In the above example, (tail (queue 1 2 3 4 5 6)), returns (queue 2 3 4 5 6).
(queue->list que) → (Queue A) |
que : (Queue A) |
Example: |
> (queue->list (queue 10 2 34 4 15 6)) |
- : (Listof Positive-Fixnum) |
'(10 2 34 4 15 6) |
(map func que1 que2 ...) → (Queue A) |
func : (A B ... B -> C) |
que1 : (Queue A) |
que2 : (Queue B) |
Examples: |
> (queue->list (map add1 (queue 1 2 3 4 5 6))) |
- : (Listof Exact-Positive-Integer) |
'(2 3 4 5 6 7) |
> (queue->list (map * (queue 1 2 3 4 5 6) (queue 1 2 3 4 5 6))) |
- : (Listof Exact-Positive-Integer) |
'(1 4 9 16 25 36) |
(fold func init que1 que2 ...) → C |
func : (C A B ... B -> C) |
init : C |
que1 : (Queue A) |
que2 : (Queue B) |
fold currently does not produce correct results when the given function is non-commutative.
Examples: |
> (fold + 0 (queue 1 2 3 4 5 6)) |
- : Exact-Nonnegative-Integer |
21 |
> (fold * 1 (queue 1 2 3 4 5 6) (queue 1 2 3 4 5 6)) |
- : Exact-Positive-Integer |
518400 |
(filter func que) → (Queue A) |
func : (A -> Boolean) |
que : (Queue A) |
Examples: |
> (define que (queue 1 2 3 4 5 6)) |
> (queue->list (filter (λ: ([x : Integer]) (> x 5)) que)) |
- : (Listof Positive-Fixnum) |
'(6) |
> (queue->list (filter (λ: ([x : Integer]) (< x 5)) que)) |
- : (Listof Positive-Fixnum) |
'(1 2 3 4) |
> (queue->list (filter (λ: ([x : Integer]) (<= x 5)) que)) |
- : (Listof Positive-Fixnum) |
'(1 2 3 4 5) |
(remove func que) → (Queue A) |
func : (A -> Boolean) |
que : (Queue A) |
Examples: | ||
| ||
- : (Listof Positive-Fixnum) | ||
'(1 2 3 4 5) | ||
| ||
- : (Listof Positive-Fixnum) | ||
'(5 6) | ||
| ||
- : (Listof Positive-Fixnum) | ||
'(6) |
1.6 Hood-Melville Queue
(require "hood-melville-queue.ss") |
Similar to Real-Time Queues in many ways. But the implementation is much more complicated than Real-Time Queue. Uses a technique called Global Rebuilding. The data structure gives a worst case running time of O(1) for the operations head, tail and enqueue.
(queue a ...) → (Queue A) |
a : A |
Example: |
> (queue 1 2 3 4 5 6) |
- : (Queue Positive-Fixnum) |
#<Queue> |
In the above example, the queue obtained will have 1 as its head element.
empty : (Queue Nothing) |
(empty? que) → Boolean |
que : (Queue A) |
Examples: |
> (empty? (queue 1 2 3 4 5 6)) |
- : Boolean |
#f |
> (empty? empty) |
- : Boolean |
#t |
(enqueue a que) → (Queue A) |
a : A |
que : (Queue A) |
In the above example, enqueue adds the element 10 to (queue 1 2 3 4 5 6) and returns (queue 1 2 3 4 5 6 10).
(head que) → A |
que : (Queue A) |
Examples: |
> (head (queue 1 2 3 4 5 6)) |
- : Positive-Fixnum |
1 |
> (head empty) |
head: given queue is empty |
(tail que) → (Queue A) |
que : (Queue A) |
Examples: |
> (tail (queue 1 2 3 4 5 6)) |
- : (Queue Positive-Fixnum) |
#<Queue> |
> (tail empty) |
tail: given queue is empty |
In the above example, (tail (queue 1 2 3 4 5 6)), returns (queue 2 3 4 5 6).
(queue->list que) → (Queue A) |
que : (Queue A) |
Examples: |
> (queue->list (queue 10 2 34 4 15 6)) |
- : (Listof Positive-Fixnum) |
'(10 2 34 4 15 6) |
> (queue->list empty) |
- : (Listof Nothing) |
'() |
(map func que1 que2 ...) → (Queue A) |
func : (A B ... B -> C) |
que1 : (Queue A) |
que2 : (Queue B) |
Examples: |
> (queue->list (map add1 (queue 1 2 3 4 5 6))) |
- : (Listof Exact-Positive-Integer) |
'(2 3 4 5 6 7) |
> (queue->list (map * (queue 1 2 3 4 5 6) (queue 1 2 3 4 5 6))) |
- : (Listof Exact-Positive-Integer) |
'(1 4 9 16 25 36) |
(fold func init que1 que2 ...) → C |
func : (C A B ... B -> C) |
init : C |
que1 : (Queue A) |
que2 : (Queue B) |
fold currently does not produce correct results when the given function is non-commutative.
Examples: |
> (fold + 0 (queue 1 2 3 4 5 6)) |
- : Exact-Nonnegative-Integer |
21 |
> (fold * 1 (queue 1 2 3 4 5 6) (queue 1 2 3 4 5 6)) |
- : Exact-Positive-Integer |
518400 |
(filter func que) → (Queue A) |
func : (A -> Boolean) |
que : (Queue A) |
Examples: |
> (define que (queue 1 2 3 4 5 6)) |
> (queue->list (filter (λ: ([x : Integer]) (> x 5)) que)) |
- : (Listof Positive-Fixnum) |
'(6) |
> (queue->list (filter (λ: ([x : Integer]) (< x 5)) que)) |
- : (Listof Positive-Fixnum) |
'(1 2 3 4) |
> (queue->list (filter (λ: ([x : Integer]) (<= x 5)) que)) |
- : (Listof Positive-Fixnum) |
'(1 2 3 4 5) |
(remove func que) → (Queue A) |
func : (A -> Boolean) |
que : (Queue A) |
Examples: | ||
| ||
- : (Listof Positive-Fixnum) | ||
'(1 2 3 4 5) | ||
| ||
- : (Listof Positive-Fixnum) | ||
'(5 6) | ||
| ||
- : (Listof Positive-Fixnum) | ||
'(6) |