2 Deques
Following Deque data structures implement and provide the functions deque, empty?, enqueue, enqueue-front, head, tail, last, init and deque->list. All the deque structures are polymorphic.
2.1 Bankers Deque
(require (planet krhari/pfds:1:5/bankers-deque)) |
Bankers Deques are Amortized double ended deques also known as deque developed using Bankers method. Provides amortized running time of O(1) for the operations head, tail, last, init, enqueue-front and enqueue. Uses lazy evaluation and memoization to achieve the amortized running time.
(Deque A) |
Example: |
> (deque 1 2 3 4 5 6) |
- : (Deque Positive-Fixnum) |
#<Deque> |
In the above example, the deque obtained will have 1 as its head element.
Examples: |
> (empty Nothing) |
- : (Deque Nothing) |
#<Deque> |
> (empty Integer) |
- : (Deque Integer) |
#<Deque> |
(enqueue-front a deq) → (Deque A) |
a : A |
deq : (Deque A) |
Example: |
> (enqueue-front 10 (deque 5 6 3 4)) |
- : (Deque Positive-Fixnum) |
#<Deque> |
In the above example, (enqueue-front 10 (deque 5 6 3 4)) adds 10 to the front of the (deque 5 6 3 4). 10 will be the head element.
Examples: |
> (head (deque 5 2 3)) |
- : Positive-Fixnum |
5 |
> (head (empty Integer)) |
head: given deque is empty |
In the above example, (head (empty Integer)) throws an error since the given deque is empty.
Examples: |
> (last (deque 1 2 3 4 5 6)) |
- : Positive-Fixnum |
6 |
> (last (empty Integer)) |
last: given deque is empty |
In the above example, (last (empty Integer))throws an error since the given deque is empty.
Examples: |
> (tail (deque 1 2 3 4 5 6)) |
- : (Deque Positive-Fixnum) |
#<Deque> |
> (tail (empty Integer)) |
tail: given deque is empty |
In the above example, (tail (deque 1 2 3 4 5 6)), removes the head of the given deque returns (deque 2 3 4 5 6).
Examples: |
> (init (deque 1 2 3 4 5 6)) |
- : (Deque Positive-Fixnum) |
#<Deque> |
> (init (empty Integer)) |
init: given deque is empty |
In the above example, (init (deque 1 2 3 4 5 6)), removes the last element 6 and returns (deque 1 2 3 4 5).
(deque->list deq) → (Listof A) |
deq : (Deque A) |
Examples: |
> (deque->list (deque 10 2 34 4 15 6)) |
- : (Listof Positive-Fixnum) |
'(10 2 34 4 15 6) |
> (deque->list (empty Integer)) |
- : (Listof Integer) |
'() |
Examples: |
> (deque->list (map add1 (deque 1 2 3 4 5 6))) |
- : (Listof Exact-Positive-Integer) |
'(2 3 4 5 6 7) |
> (deque->list (map * (deque 1 2 3 4 5 6) (deque 1 2 3 4 5 6))) |
- : (Listof Exact-Positive-Integer) |
'(1 4 9 16 25 36) |
(foldl func init deq1 deq2 ...) → C |
func : (C A B ... B -> C) |
init : C |
deq1 : (Deque A) |
deq2 : (Deque B) |
foldl currently does not produce correct results when the given function is non-commutative.
Examples: |
> (foldl + 0 (deque 1 2 3 4 5 6)) |
- : Exact-Nonnegative-Integer |
21 |
> (foldl * 1 (deque 1 2 3 4 5 6) (deque 1 2 3 4 5 6)) |
- : Exact-Positive-Integer |
518400 |
(foldr func init deq1 deq2 ...) → C |
func : (C A B ... B -> C) |
init : C |
deq1 : (Deque A) |
deq2 : (Deque B) |
foldr currently does not produce correct results when the given function is non-commutative.
Examples: |
> (foldr + 0 (deque 1 2 3 4 5 6)) |
- : Exact-Nonnegative-Integer |
21 |
> (foldr * 1 (deque 1 2 3 4 5 6) (deque 1 2 3 4 5 6)) |
- : Exact-Positive-Integer |
518400 |
Examples: |
> (define que (deque 1 2 3 4 5 6)) |
> (deque->list (filter (λ: ([x : Integer]) (> x 5)) que)) |
- : (Listof Positive-Fixnum) |
'(6) |
> (deque->list (filter (λ: ([x : Integer]) (< x 5)) que)) |
- : (Listof Positive-Fixnum) |
'(1 2 3 4) |
> (deque->list (filter (λ: ([x : Integer]) (<= x 5)) que)) |
- : (Listof Positive-Fixnum) |
'(1 2 3 4 5) |
Examples: | ||
| ||
- : (Listof Positive-Fixnum) | ||
'(1 2 3 4 5) | ||
| ||
- : (Listof Positive-Fixnum) | ||
'(5 6) | ||
| ||
- : (Listof Positive-Fixnum) | ||
'(6) |
(andmap func deq1 deq2 ...) → Boolean |
func : (A B ... B -> Boolean) |
deq1 : (Deque A) |
deq2 : (Deque B) |
Examples: |
> (andmap even? (deque 1 2 3 4 5 6)) |
- : Boolean |
#f |
> (andmap odd? (deque 1 2 3 4 5 6)) |
- : Boolean |
#f |
> (andmap positive? (deque 1 2 3 4 5 6)) |
- : Boolean |
#t |
> (andmap negative? (deque -1 -2)) |
- : Boolean |
#t |
(ormap func deq1 deq2 ...) → Boolean |
func : (A B ... B -> Boolean) |
deq1 : (Deque A) |
deq2 : (Deque B) |
Examples: |
> (ormap even? (deque 1 2 3 4 5 6)) |
- : Boolean |
#t |
> (ormap odd? (deque 1 2 3 4 5 6)) |
- : Boolean |
#t |
> (ormap positive? (deque -1 -2 3 4 -5 6)) |
- : Boolean |
#t |
> (ormap negative? (deque 1 -2)) |
- : Boolean |
#t |
(build-deque size func) → (Deque A) |
size : Natural |
func : (Natural -> A) |
Examples: |
> (deque->list (build-deque 5 (λ:([x : Integer]) (add1 x)))) |
- : (Listof Integer) |
'(1 2 3 4 5) |
> (deque->list (build-deque 5 (λ:([x : Integer]) (* x x)))) |
- : (Listof Integer) |
'(0 1 4 9 16) |
Examples: |
> (head+tail (deque 1 2 3 4 5)) |
- : (Pairof Positive-Fixnum (Deque Positive-Fixnum)) |
'(1 . #<Deque>) |
> (head+tail (build-deque 5 (λ:([x : Integer]) (* x x)))) |
- : (Pairof Integer (Deque Integer)) |
'(0 . #<Deque>) |
> (head+tail (empty Integer)) |
head+tail: given deque is empty |
Examples: |
> (last+init (deque 1 2 3 4 5)) |
- : (Pairof Positive-Fixnum (Deque Positive-Fixnum)) |
'(5 . #<Deque>) |
> (last+init (build-deque 5 (λ:([x : Integer]) (* x x)))) |
- : (Pairof Integer (Deque Integer)) |
'(16 . #<Deque>) |
> (last+init (empty Integer)) |
last+init: given deque is empty |
2.2 Implicit Deque
(require (planet krhari/pfds:1:5/implicitdeque)) |
Deques obtained by applying Implicit Recursive Slowdown. Provides amortized running time of O(1) for the operations head, tail, last, init, enqueue-front 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.
(Deque A) |
Example: |
> (deque 1 2 3 4 5 6) |
- : (U (Shallow Positive-Fixnum) (Deep Positive-Fixnum)) |
#<Deep> |
In the above example, the deque obtained will have 1 as its head element.
Examples: |
> (empty? (deque 1 2 3 4 5 6)) |
- : Boolean |
#f |
> (empty? empty) |
- : Boolean |
#t |
Example: |
> (enqueue 10 (deque 1 2 3 4 5 6)) |
- : (U (Shallow Positive-Fixnum) (Deep Positive-Fixnum)) |
#<Deep> |
In the above example, enqueue adds the element 10 to (deque 1 2 3 4 5 6 10).
(enqueue-front a deq) → (Deque A) |
a : A |
deq : (Deque A) |
Example: |
> (enqueue-front 10 (deque 5 6 3 4)) |
- : (U (Shallow Positive-Fixnum) (Deep Positive-Fixnum)) |
#<Deep> |
In the above example, (enqueue-front 10 (deque 5 6 3 4)) adds 10 to the front of the (deque 5 6 3 4). 10 will be the head element.
Examples: |
> (head (deque 1 2 3 4 5 6)) |
- : Positive-Fixnum |
1 |
> (head empty) |
head: given deque is empty |
Examples: |
> (last (deque 1 2 3 4 5 6)) |
- : Positive-Fixnum |
6 |
> (last empty) |
last: given deque is empty |
Examples: |
> (tail (deque 1 2 3 4 5 6)) |
- : (U (Shallow Positive-Fixnum) (Deep Positive-Fixnum)) |
#<Deep> |
> (tail empty) |
tail: given deque is empty |
In the above example, (tail (deque 1 2 3 4 5 6)), removes 1 and returns (tail (deque 2 3 4 5 6)).
Examples: |
> (init (deque 1 2 3 4 5 6)) |
- : (U (Shallow Positive-Fixnum) (Deep Positive-Fixnum)) |
#<Deep> |
> (init empty) |
init: given deque is empty |
In the above example, (init (deque 1 2 3 4 5 6)), removes the last element 6 and returns (deque 1 2 3 4 5)
(deque->list deq) → (Listof A) |
deq : (Deque A) |
Example: |
> (deque->list (deque 10 2 34 4 15 6)) |
- : (Listof Positive-Fixnum) |
'(10 2 34 4 15 6) |
Examples: |
> (deque->list (map add1 (deque 1 2 3 4 5 6))) |
- : (Listof Exact-Positive-Integer) |
'(2 3 4 5 6 7) |
> (deque->list (map * (deque 1 2 3 4 5 6) (deque 1 2 3 4 5 6))) |
- : (Listof Exact-Positive-Integer) |
'(1 4 9 16 25 36) |
(foldl func init deq1 deq2 ...) → C |
func : (C A B ... B -> C) |
init : C |
deq1 : (Deque A) |
deq2 : (Deque B) |
foldl currently does not produce correct results when the given function is non-commutative.
Examples: |
> (foldl + 0 (deque 1 2 3 4 5 6)) |
- : Exact-Nonnegative-Integer |
21 |
> (foldl * 1 (deque 1 2 3 4 5 6) (deque 1 2 3 4 5 6)) |
- : Exact-Positive-Integer |
518400 |
(foldr func init deq1 deq2 ...) → C |
func : (C A B ... B -> C) |
init : C |
deq1 : (Deque A) |
deq2 : (Deque B) |
foldr currently does not produce correct results when the given function is non-commutative.
Examples: |
> (foldr + 0 (deque 1 2 3 4 5 6)) |
- : Exact-Nonnegative-Integer |
21 |
> (foldr * 1 (deque 1 2 3 4 5 6) (deque 1 2 3 4 5 6)) |
- : Exact-Positive-Integer |
518400 |
Examples: |
> (define que (deque 1 2 3 4 5 6)) |
> (deque->list (filter (λ: ([x : Integer]) (> x 5)) que)) |
- : (Listof Positive-Fixnum) |
'(6) |
> (deque->list (filter (λ: ([x : Integer]) (< x 5)) que)) |
- : (Listof Positive-Fixnum) |
'(1 2 3 4) |
> (deque->list (filter (λ: ([x : Integer]) (<= x 5)) que)) |
- : (Listof Positive-Fixnum) |
'(1 2 3 4 5) |
Examples: | ||
| ||
- : (Listof Positive-Fixnum) | ||
'(1 2 3 4 5) | ||
| ||
- : (Listof Positive-Fixnum) | ||
'(5 6) | ||
| ||
- : (Listof Positive-Fixnum) | ||
'(6) |
(andmap func deq1 deq2 ...) → Boolean |
func : (A B ... B -> Boolean) |
deq1 : (Deque A) |
deq2 : (Deque B) |
Examples: |
> (andmap even? (deque 1 2 3 4 5 6)) |
- : Boolean |
#f |
> (andmap odd? (deque 1 2 3 4 5 6)) |
- : Boolean |
#f |
> (andmap positive? (deque 1 2 3 4 5 6)) |
- : Boolean |
#t |
> (andmap negative? (deque -1 -2)) |
- : Boolean |
#t |
(ormap func deq1 deq2 ...) → Boolean |
func : (A B ... B -> Boolean) |
deq1 : (Deque A) |
deq2 : (Deque B) |
Examples: |
> (ormap even? (deque 1 2 3 4 5 6)) |
- : Boolean |
#t |
> (ormap odd? (deque 1 2 3 4 5 6)) |
- : Boolean |
#t |
> (ormap positive? (deque -1 -2 3 4 -5 6)) |
- : Boolean |
#t |
> (ormap negative? (deque 1 -2)) |
- : Boolean |
#t |
(build-deque size func) → (Deque A) |
size : Natural |
func : (Natural -> A) |
Examples: |
> (deque->list (build-deque 5 (λ:([x : Integer]) (add1 x)))) |
- : (Listof Integer) |
'(1 2 3 4 5) |
> (deque->list (build-deque 5 (λ:([x : Integer]) (* x x)))) |
- : (Listof Integer) |
'(0 1 4 9 16) |
Examples: |
> (head+tail (deque 1 2 3 4 5)) |
- : (Pairof Positive-Fixnum (U (Shallow Positive-Fixnum) (Deep Positive-Fixnum))) |
'(1 . #<Deep>) |
> (head+tail (build-deque 5 (λ:([x : Integer]) (* x x)))) |
- : (Pairof Integer (U (Shallow Integer) (Deep Integer))) |
'(0 . #<Deep>) |
> (head+tail empty) |
head+tail: given deque is empty |
Examples: |
> (last+init (deque 1 2 3 4 5)) |
- : (Pairof Positive-Fixnum (U (Shallow Positive-Fixnum) (Deep Positive-Fixnum))) |
'(5 . #<Deep>) |
> (last+init (build-deque 5 (λ:([x : Integer]) (* x x)))) |
- : (Pairof Integer (U (Shallow Integer) (Deep Integer))) |
'(16 . #<Deep>) |
> (last+init empty) |
last+init: given deque is empty |
2.3 Real-Time Deque
(require (planet krhari/pfds:1:5/realtimedeque)) |
Real-Time Deques eliminate the amortization by using two techniques Scheduling and a variant of Global Rebuilding called Lazy Rebuilding. The data structure gives a worst case running time of O(1) for the operations head, tail, last, init, enqueue-front and enqueue.
(Deque A) |
Example: |
> (deque 1 2 3 4 5 6) |
- : (Deque Positive-Fixnum) |
#<Deque> |
In the above example, the deque obtained will have 1 as its head element.
Examples: |
> (empty? (deque 1 2 3 4 5 6)) |
- : Boolean |
#f |
> (empty? (empty Integer)) |
- : Boolean |
#t |
In the above example, enqueue adds the element 10 to the end of (deque 1 2 3 4 5 6).
(enqueue-front a deq) → (Deque A) |
a : A |
deq : (Deque A) |
Example: |
> (enqueue-front 10 (deque 1 2 3 4 5 6)) |
- : (Deque Positive-Fixnum) |
#<Deque> |
In the above example, enqueue adds the element 10 to the front of (deque 1 2 3 4 5 6) and returns (deque 10 1 2 3 4 5 6).
Examples: |
> (head (deque 1 2 3 4 5 6)) |
- : Positive-Fixnum |
1 |
> (head (empty Integer)) |
head: given deque is empty |
Examples: |
> (last (deque 1 2 3 4 5 6)) |
- : Positive-Fixnum |
6 |
> (last (empty Integer)) |
last: given deque is empty |
Examples: |
> (tail (deque 1 2 3 4 5 6)) |
- : (Deque Positive-Fixnum) |
#<Deque> |
> (tail (empty Integer)) |
tail: given deque is empty |
In the above example, (tail (deque 1 2 3 4 5 6)), removes the head of the given deque returns (deque 2 3 4 5 6).
Examples: |
> (init (deque 1 2 3 4 5 6)) |
- : (Deque Positive-Fixnum) |
#<Deque> |
> (init (empty Integer)) |
init: given deque is empty |
In the above example, (init (deque 1 2 3 4 5 6)), removes the last element 6 of the given deque and returns (deque 1 2 3 4 5).
(deque->list deq) → (Listof A) |
deq : (Deque A) |
Example: |
> (deque->list (deque 10 2 34 4 15 6)) |
- : (Listof Positive-Fixnum) |
'(10 2 34 4 15 6) |
Examples: |
> (deque->list (map add1 (deque 1 2 3 4 5 6))) |
- : (Listof Exact-Positive-Integer) |
'(2 3 4 5 6 7) |
> (deque->list (map * (deque 1 2 3 4 5 6) (deque 1 2 3 4 5 6))) |
- : (Listof Exact-Positive-Integer) |
'(1 4 9 16 25 36) |
(foldl func init deq1 deq2 ...) → C |
func : (C A B ... B -> C) |
init : C |
deq1 : (Deque A) |
deq2 : (Deque B) |
foldl currently does not produce correct results when the given function is non-commutative.
Examples: |
> (foldl + 0 (deque 1 2 3 4 5 6)) |
- : Exact-Nonnegative-Integer |
21 |
> (foldl * 1 (deque 1 2 3 4 5 6) (deque 1 2 3 4 5 6)) |
- : Exact-Positive-Integer |
518400 |
(foldr func init deq1 deq2 ...) → C |
func : (C A B ... B -> C) |
init : C |
deq1 : (Deque A) |
deq2 : (Deque B) |
foldr currently does not produce correct results when the given function is non-commutative.
Examples: |
> (foldr + 0 (deque 1 2 3 4 5 6)) |
- : Exact-Nonnegative-Integer |
21 |
> (foldr * 1 (deque 1 2 3 4 5 6) (deque 1 2 3 4 5 6)) |
- : Exact-Positive-Integer |
518400 |
Examples: |
> (define que (deque 1 2 3 4 5 6)) |
> (deque->list (filter (λ: ([x : Integer]) (> x 5)) que)) |
- : (Listof Positive-Fixnum) |
'(6) |
> (deque->list (filter (λ: ([x : Integer]) (< x 5)) que)) |
- : (Listof Positive-Fixnum) |
'(1 2 3 4) |
> (deque->list (filter (λ: ([x : Integer]) (<= x 5)) que)) |
- : (Listof Positive-Fixnum) |
'(1 2 3 4 5) |
Examples: | ||
| ||
- : (Listof Positive-Fixnum) | ||
'(1 2 3 4 5) | ||
| ||
- : (Listof Positive-Fixnum) | ||
'(5 6) | ||
| ||
- : (Listof Positive-Fixnum) | ||
'(6) |
(andmap func deq1 deq2 ...) → Boolean |
func : (A B ... B -> Boolean) |
deq1 : (Deque A) |
deq2 : (Deque B) |
Examples: |
> (andmap even? (deque 1 2 3 4 5 6)) |
- : Boolean |
#f |
> (andmap odd? (deque 1 2 3 4 5 6)) |
- : Boolean |
#f |
> (andmap positive? (deque 1 2 3 4 5 6)) |
- : Boolean |
#t |
> (andmap negative? (deque -1 -2)) |
- : Boolean |
#t |
(ormap func deq1 deq2 ...) → Boolean |
func : (A B ... B -> Boolean) |
deq1 : (Deque A) |
deq2 : (Deque B) |
Examples: |
> (ormap even? (deque 1 2 3 4 5 6)) |
- : Boolean |
#t |
> (ormap odd? (deque 1 2 3 4 5 6)) |
- : Boolean |
#t |
> (ormap positive? (deque -1 -2 3 4 -5 6)) |
- : Boolean |
#t |
> (ormap negative? (deque 1 -2)) |
- : Boolean |
#t |
(build-deque size func) → (Deque A) |
size : Natural |
func : (Natural -> A) |
Examples: |
> (deque->list (build-deque 5 (λ:([x : Integer]) (add1 x)))) |
- : (Listof Integer) |
'(1 2 3 4 5) |
> (deque->list (build-deque 5 (λ:([x : Integer]) (* x x)))) |
- : (Listof Integer) |
'(0 1 4 9 16) |
Examples: |
> (head+tail (deque 1 2 3 4 5)) |
- : (Pairof Positive-Fixnum (Deque Positive-Fixnum)) |
'(1 . #<Deque>) |
> (head+tail (build-deque 5 (λ:([x : Integer]) (* x x)))) |
- : (Pairof Integer (Deque Integer)) |
'(0 . #<Deque>) |
> (head+tail (empty Integer)) |
head+tail: given deque is empty |