2 Deques
Double ended queues (or deque) are queues where elements can be added or removed from either end. The deque data structures provided by this library implement and provide the following operations: deque, empty?, enqueue, enqueue-front, head, tail, last, init and deque->list.
2.1 Bankers Deque
(require pfds/deque/bankers) | package: pfds |
Bankers deques are amortized double ended deques developed using the Bankers method. They provide an amortized running time of O(1) for the operations head, tail, last, init, enqueue-front and enqueue. They use lazy evaluation and memoization to achieve the amortized running time.
syntax
(Deque A)
> (deque 1 2 3 4 5 6)
- : #(struct:Deque
((Rec
g305665
(U (Pairof Positive-Byte g305665) (Promiseof g305665) Null))
Integer
(Rec
g305667
(U (Pairof Positive-Byte g305667) (Promiseof g305667) Null))
Integer))
#<Deque>
In the above example, the deque obtained will have 1 as its head element.
procedure
(enqueue-front a deq) β (Deque A)
a : A deq : (Deque A)
> (enqueue-front 10 (deque 5 6 3 4))
- : #(struct:Deque
((Rec
g305758
(U (Pairof Positive-Byte g305758) (Promiseof g305758) Null))
Integer
(Rec
g305760
(U (Pairof Positive-Byte g305760) (Promiseof g305760) Null))
Integer))
#<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.
In the above example, (head (empty Integer)) throws an error since the given deque is empty.
In the above example, (last (empty Integer))throws an error since the 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).
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).
procedure
(deque->list deq) β (Listof A)
deq : (Deque A)
> (deque->list (deque 10 2 34 4 15 6)) - : (Listof Positive-Byte)
'(10 2 34 4 15 6)
> (deque->list (empty Integer)) - : (Listof Integer)
'()
> (deque->list (map add1 (deque 1 2 3 4 5 6))) - : (Listof Positive-Index)
'(2 3 4 5 6 7)
> (deque->list (map * (deque 1 2 3 4 5 6) (deque 1 2 3 4 5 6))) - : (Listof Positive-Index)
'(1 4 9 16 25 36)
procedure
(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.
> (foldl + 0 (deque 1 2 3 4 5 6)) - : Integer [more precisely: Nonnegative-Integer]
21
> (foldl * 1 (deque 1 2 3 4 5 6) (deque 1 2 3 4 5 6)) - : Integer [more precisely: Positive-Integer]
518400
procedure
(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.
> (foldr + 0 (deque 1 2 3 4 5 6)) - : Integer [more precisely: Nonnegative-Integer]
21
> (foldr * 1 (deque 1 2 3 4 5 6) (deque 1 2 3 4 5 6)) - : Integer [more precisely: Positive-Integer]
518400
> (define que (deque 1 2 3 4 5 6)) > (deque->list (filter (Ξ»: ([x : Integer]) (> x 5)) que)) - : (Listof Positive-Byte)
'(6)
> (deque->list (filter (Ξ»: ([x : Integer]) (< x 5)) que)) - : (Listof Positive-Byte)
'(1 2 3 4)
> (deque->list (filter (Ξ»: ([x : Integer]) (<= x 5)) que)) - : (Listof Positive-Byte)
'(1 2 3 4 5)
> (deque->list (remove (Ξ»: ([x : Integer]) (> x 5)) (deque 1 2 3 4 5 6))) - : (Listof Positive-Byte)
'(1 2 3 4 5)
> (deque->list (remove (Ξ»: ([x : Integer]) (< x 5)) (deque 1 2 3 4 5 6))) - : (Listof Positive-Byte)
'(5 6)
> (deque->list (remove (Ξ»: ([x : Integer]) (<= x 5)) (deque 1 2 3 4 5 6))) - : (Listof Positive-Byte)
'(6)
procedure
(andmap func deq1 deq2 ...) β Boolean
func : (A B ... B -> Boolean) deq1 : (Deque A) deq2 : (Deque B)
> (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
procedure
(ormap func deq1 deq2 ...) β Boolean
func : (A B ... B -> Boolean) deq1 : (Deque A) deq2 : (Deque B)
> (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
procedure
(build-deque size func) β (Deque A)
size : Natural func : (Natural -> A)
> (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)
> (head+tail (deque 1 2 3 4 5))
- : (Pairof
Positive-Byte
#(struct:Deque
((Rec
g306569
(U (Pairof Positive-Byte g306569) (Promiseof g306569) Null))
Integer
(Rec
g306571
(U (Pairof Positive-Byte g306571) (Promiseof g306571) Null))
Integer)))
'(1 . #<Deque>)
> (head+tail (build-deque 5 (Ξ»:([x : Integer]) (* x x))))
- : (Pairof
Integer
#(struct:Deque
((Rec g306595 (U (Pairof Integer g306595) (Promiseof g306595) Null))
Integer
(Rec g306597 (U (Pairof Integer g306597) (Promiseof g306597) Null))
Integer)))
'(0 . #<Deque>)
> (head+tail (empty Integer)) head+tail: given deque is empty
> (last+init (deque 1 2 3 4 5))
- : (Pairof
Positive-Byte
#(struct:Deque
((Rec
g306638
(U (Pairof Positive-Byte g306638) (Promiseof g306638) Null))
Integer
(Rec
g306640
(U (Pairof Positive-Byte g306640) (Promiseof g306640) Null))
Integer)))
'(5 . #<Deque>)
> (last+init (build-deque 5 (Ξ»:([x : Integer]) (* x x))))
- : (Pairof
Integer
#(struct:Deque
((Rec g306664 (U (Pairof Integer g306664) (Promiseof g306664) Null))
Integer
(Rec g306666 (U (Pairof Integer g306666) (Promiseof g306666) Null))
Integer)))
'(16 . #<Deque>)
> (last+init (empty Integer)) last+init: given deque is empty
2.2 Implicit Deque
(require pfds/deque/implicit) | package: pfds |
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.
syntax
(Deque A)
> (deque 1 2 3 4 5 6) - : (U (Deep Positive-Byte) (Shallow Positive-Byte))
#<Deep>
In the above example, the deque obtained will have 1 as its head element.
In the above example, enqueue adds the element 10 to (deque 1 2 3 4 5 6 10).
procedure
(enqueue-front a deq) β (Deque A)
a : A deq : (Deque A)
> (enqueue-front 10 (deque 5 6 3 4)) - : (U (Deep Positive-Byte) (Shallow Positive-Byte))
#<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.
In the above example, (tail (deque 1 2 3 4 5 6)), removes 1 and returns (tail (deque 2 3 4 5 6)).
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)
procedure
(deque->list deq) β (Listof A)
deq : (Deque A)
> (deque->list (deque 10 2 34 4 15 6)) - : (Listof Positive-Byte)
'(10 2 34 4 15 6)
> (deque->list (map add1 (deque 1 2 3 4 5 6))) - : (Listof Positive-Index)
'(2 3 4 5 6 7)
> (deque->list (map * (deque 1 2 3 4 5 6) (deque 1 2 3 4 5 6))) - : (Listof Positive-Index)
'(1 4 9 16 25 36)
procedure
(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.
> (foldl + 0 (deque 1 2 3 4 5 6)) - : Integer [more precisely: Nonnegative-Integer]
21
> (foldl * 1 (deque 1 2 3 4 5 6) (deque 1 2 3 4 5 6)) - : Integer [more precisely: Positive-Integer]
518400
procedure
(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.
> (foldr + 0 (deque 1 2 3 4 5 6)) - : Integer [more precisely: Nonnegative-Integer]
21
> (foldr * 1 (deque 1 2 3 4 5 6) (deque 1 2 3 4 5 6)) - : Integer [more precisely: Positive-Integer]
518400
> (define que (deque 1 2 3 4 5 6)) > (deque->list (filter (Ξ»: ([x : Integer]) (> x 5)) que)) - : (Listof Positive-Byte)
'(6)
> (deque->list (filter (Ξ»: ([x : Integer]) (< x 5)) que)) - : (Listof Positive-Byte)
'(1 2 3 4)
> (deque->list (filter (Ξ»: ([x : Integer]) (<= x 5)) que)) - : (Listof Positive-Byte)
'(1 2 3 4 5)
> (deque->list (remove (Ξ»: ([x : Integer]) (> x 5)) (deque 1 2 3 4 5 6))) - : (Listof Positive-Byte)
'(1 2 3 4 5)
> (deque->list (remove (Ξ»: ([x : Integer]) (< x 5)) (deque 1 2 3 4 5 6))) - : (Listof Positive-Byte)
'(5 6)
> (deque->list (remove (Ξ»: ([x : Integer]) (<= x 5)) (deque 1 2 3 4 5 6))) - : (Listof Positive-Byte)
'(6)
procedure
(andmap func deq1 deq2 ...) β Boolean
func : (A B ... B -> Boolean) deq1 : (Deque A) deq2 : (Deque B)
> (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
procedure
(ormap func deq1 deq2 ...) β Boolean
func : (A B ... B -> Boolean) deq1 : (Deque A) deq2 : (Deque B)
> (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
procedure
(build-deque size func) β (Deque A)
size : Natural func : (Natural -> A)
> (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)
> (last+init (deque 1 2 3 4 5)) - : (Pairof Positive-Byte (U (Deep Positive-Byte) (Shallow Positive-Byte)))
'(5 . #<Deep>)
> (last+init (build-deque 5 (Ξ»:([x : Integer]) (* x x)))) - : (Pairof Integer (U (Deep Integer) (Shallow Integer)))
'(16 . #<Deep>)
> (last+init empty) last+init: given deque is empty
2.3 Real-Time Deque
(require pfds/deque/real-time) | package: pfds |
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.
syntax
(Deque A)
> (deque 1 2 3 4 5 6)
- : #(struct:Deque
((Rec
g310311
(U (Boxof (U (-> (Pairof Integer g310311)) (Pairof Integer g310311)))
Null))
Integer
(Rec
g310314
(U (Boxof (U (-> (Pairof Integer g310314)) (Pairof Integer g310314)))
Null))
(Rec
g310317
(U (Boxof (U (-> (Pairof Integer g310317)) (Pairof Integer g310317)))
Null))
Integer
(Rec
g310320
(U (Boxof (U (-> (Pairof Integer g310320)) (Pairof Integer g310320)))
Null))))
#<Deque>
In the above example, the deque obtained will have 1 as its head element.
> (enqueue 10 (deque 1 2 3 4 5 6))
- : #(struct:Deque
((Rec
g310352
(U (Boxof (U (-> (Pairof Integer g310352)) (Pairof Integer g310352)))
Null))
Integer
(Rec
g310355
(U (Boxof (U (-> (Pairof Integer g310355)) (Pairof Integer g310355)))
Null))
(Rec
g310358
(U (Boxof (U (-> (Pairof Integer g310358)) (Pairof Integer g310358)))
Null))
Integer
(Rec
g310361
(U (Boxof (U (-> (Pairof Integer g310361)) (Pairof Integer g310361)))
Null))))
#<Deque>
In the above example, enqueue adds the element 10 to the end of (deque 1 2 3 4 5 6).
procedure
(enqueue-front a deq) β (Deque A)
a : A deq : (Deque A)
> (enqueue-front 10 (deque 1 2 3 4 5 6))
- : #(struct:Deque
((Rec
g310373
(U (Boxof (U (-> (Pairof Integer g310373)) (Pairof Integer g310373)))
Null))
Integer
(Rec
g310376
(U (Boxof (U (-> (Pairof Integer g310376)) (Pairof Integer g310376)))
Null))
(Rec
g310379
(U (Boxof (U (-> (Pairof Integer g310379)) (Pairof Integer g310379)))
Null))
Integer
(Rec
g310382
(U (Boxof (U (-> (Pairof Integer g310382)) (Pairof Integer g310382)))
Null))))
#<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).
> (tail (deque 1 2 3 4 5 6))
- : #(struct:Deque
((Rec
g310432
(U (Boxof (U (-> (Pairof Integer g310432)) (Pairof Integer g310432)))
Null))
Integer
(Rec
g310435
(U (Boxof (U (-> (Pairof Integer g310435)) (Pairof Integer g310435)))
Null))
(Rec
g310438
(U (Boxof (U (-> (Pairof Integer g310438)) (Pairof Integer g310438)))
Null))
Integer
(Rec
g310441
(U (Boxof (U (-> (Pairof Integer g310441)) (Pairof Integer g310441)))
Null))))
#<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).
> (init (deque 1 2 3 4 5 6))
- : #(struct:Deque
((Rec
g310475
(U (Boxof (U (-> (Pairof Integer g310475)) (Pairof Integer g310475)))
Null))
Integer
(Rec
g310478
(U (Boxof (U (-> (Pairof Integer g310478)) (Pairof Integer g310478)))
Null))
(Rec
g310481
(U (Boxof (U (-> (Pairof Integer g310481)) (Pairof Integer g310481)))
Null))
Integer
(Rec
g310484
(U (Boxof (U (-> (Pairof Integer g310484)) (Pairof Integer g310484)))
Null))))
#<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).
procedure
(deque->list deq) β (Listof A)
deq : (Deque A)
> (deque->list (deque 10 2 34 4 15 6)) - : (Listof Integer)
'(10 2 34 4 15 6)
> (deque->list (map add1 (deque 1 2 3 4 5 6))) - : (Listof 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 Integer)
'(1 4 9 16 25 36)
procedure
(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.
> (foldl + 0 (deque 1 2 3 4 5 6)) - : Integer
21
> (foldl * 1 (deque 1 2 3 4 5 6) (deque 1 2 3 4 5 6)) - : Integer
518400
procedure
(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.
> (foldr + 0 (deque 1 2 3 4 5 6)) - : Integer
21
> (foldr * 1 (deque 1 2 3 4 5 6) (deque 1 2 3 4 5 6)) - : Integer
518400
> (define que (deque 1 2 3 4 5 6)) > (deque->list (filter (Ξ»: ([x : Integer]) (> x 5)) que)) - : (Listof Integer)
'(6)
> (deque->list (filter (Ξ»: ([x : Integer]) (< x 5)) que)) - : (Listof Integer)
'(1 2 3 4)
> (deque->list (filter (Ξ»: ([x : Integer]) (<= x 5)) que)) - : (Listof Integer)
'(1 2 3 4 5)
> (deque->list (remove (Ξ»: ([x : Integer]) (> x 5)) (deque 1 2 3 4 5 6))) - : (Listof Integer)
'(1 2 3 4 5)
> (deque->list (remove (Ξ»: ([x : Integer]) (< x 5)) (deque 1 2 3 4 5 6))) - : (Listof Integer)
'(5 6)
> (deque->list (remove (Ξ»: ([x : Integer]) (<= x 5)) (deque 1 2 3 4 5 6))) - : (Listof Integer)
'(6)
procedure
(andmap func deq1 deq2 ...) β Boolean
func : (A B ... B -> Boolean) deq1 : (Deque A) deq2 : (Deque B)
> (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
procedure
(ormap func deq1 deq2 ...) β Boolean
func : (A B ... B -> Boolean) deq1 : (Deque A) deq2 : (Deque B)
> (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
procedure
(build-deque size func) β (Deque A)
size : Natural func : (Natural -> A)
> (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)
> (head+tail (deque 1 2 3 4 5))
- : (Pairof
Integer
#(struct:Deque
((Rec
g310858
(U (Boxof (U (-> (Pairof Integer g310858)) (Pairof Integer g310858)))
Null))
Integer
(Rec
g310861
(U (Boxof (U (-> (Pairof Integer g310861)) (Pairof Integer g310861)))
Null))
(Rec
g310864
(U (Boxof (U (-> (Pairof Integer g310864)) (Pairof Integer g310864)))
Null))
Integer
(Rec
g310867
(U (Boxof (U (-> (Pairof Integer g310867)) (Pairof Integer g310867)))
Null)))))
'(1 . #<Deque>)
> (head+tail (build-deque 5 (Ξ»:([x : Integer]) (* x x))))
- : (Pairof
Integer
#(struct:Deque
((Rec
g310884
(U (Boxof (U (-> (Pairof Integer g310884)) (Pairof Integer g310884)))
Null))
Integer
(Rec
g310887
(U (Boxof (U (-> (Pairof Integer g310887)) (Pairof Integer g310887)))
Null))
(Rec
g310890
(U (Boxof (U (-> (Pairof Integer g310890)) (Pairof Integer g310890)))
Null))
Integer
(Rec
g310893
(U (Boxof (U (-> (Pairof Integer g310893)) (Pairof Integer g310893)))
Null)))))
'(0 . #<Deque>)
> (head+tail (empty Integer)) head+tail: given deque is empty
> (last+init (deque 1 2 3 4 5))
- : (Pairof
Integer
#(struct:Deque
((Rec
g310927
(U (Boxof (U (-> (Pairof Integer g310927)) (Pairof Integer g310927)))
Null))
Integer
(Rec
g310930
(U (Boxof (U (-> (Pairof Integer g310930)) (Pairof Integer g310930)))
Null))
(Rec
g310933
(U (Boxof (U (-> (Pairof Integer g310933)) (Pairof Integer g310933)))
Null))
Integer
(Rec
g310936
(U (Boxof (U (-> (Pairof Integer g310936)) (Pairof Integer g310936)))
Null)))))
'(5 . #<Deque>)
> (last+init (build-deque 5 (Ξ»:([x : Integer]) (* x x))))
- : (Pairof
Integer
#(struct:Deque
((Rec
g310953
(U (Boxof (U (-> (Pairof Integer g310953)) (Pairof Integer g310953)))
Null))
Integer
(Rec
g310956
(U (Boxof (U (-> (Pairof Integer g310956)) (Pairof Integer g310956)))
Null))
(Rec
g310959
(U (Boxof (U (-> (Pairof Integer g310959)) (Pairof Integer g310959)))
Null))
Integer
(Rec
g310962
(U (Boxof (U (-> (Pairof Integer g310962)) (Pairof Integer g310962)))
Null)))))
'(16 . #<Deque>)
> (last+init (empty Integer)) last+init: given deque is empty