queue.ml
· 5.8 KiB · OCaml
Bruto
Playground
(* Chris Okasaki
School of Computer Science
Carnegie Mellon University
Pittsburgh, PA 15213
cokasaki@cs.cmu.edu *)
functor HoodMelvilleQueue () : QUEUE =
(* Alternative implementation of queues with O(1) worst-case *)
(* performance. Provided for comparison. *)
(* *)
(* Taken from *)
(* Hood and Melville *)
(* "Real-time queue operations in pure Lisp" *)
(* IPL 13(2) (Nov 1981), 50-53 *)
(* *)
(* Warning! Does not support insertf! *)
struct
datatype 'a Queue =
Simple of
{front : 'a list,
rear : 'a list,
diff : int} (* diff = length front - length rear *)
| Copy1 of (* in process of reversing f and r *)
{ oldfront : 'a list,
rear : 'a list,
f : 'a list,
r : 'a list,
frev : 'a list,
rrev : 'a list, (* the partial new front *)
diff : int, (* diff = length rrev - length rear *)
copy : int} (* copy = # of valid elements in frev *)
| Copy2 of (* in process of reversing frev onto newfront *)
{ oldfront : 'a list,
rear : 'a list,
frev : 'a list,
newfront : 'a list,
diff : int, (* diff = length newfront - length rear *)
copy : int} (* copy = # of valid elements in frev *)
(* begin process of moving elements from rear to front *)
fun rotate (front,rear) = (* length rear = length front + 1 *)
Copy1 { oldfront = front
, rear = []
, f = front
, r = rear
, frev = []
, rrev = []
, diff = 0
, copy = 0 }
(* do one step in process of moving elements from rear to front *)
fun tick (Copy1 {oldfront, rear, f=x::f, r=y::r, frev, rrev, diff, copy}) =
Copy1 { oldfront = oldfront
, rear = rear
, f = f
, r = r
, frev = x::frev
, rrev = y::rrev
, diff = diff + 1
, copy = copy + 1 }
| tick (Copy1 {oldfront, rear, f=[], r=[y], frev, rrev, diff, copy}) =
Copy2 { oldfront = oldfront
, rear = rear
, frev = frev
, newfront = y::rrev
, diff = diff + 1
, copy = copy }
| tick (Copy2 {oldfront, rear, newfront, diff, copy = 0, frev}) =
Simple { front = newfront
, rear = rear
, diff = diff
}
| tick (Copy2 {oldfront, rear, newfront, diff, copy = 1, frev = x::_}) =
Simple { front = x::newfront
, rear = rear
, diff = diff + 1
}
| tick (Copy2 {oldfront, rear, newfront, diff, copy, frev = x::frev}) =
Copy2 { oldfront = oldfront
, rear = rear
, newfront = x::newfront
, frev = frev
, diff = diff + 1
, copy = copy - 1 }
| tick simpleq = simpleq
fun tick2 q = tick (tick q)
exception Empty
val empty = Simple {front = [], rear = [], diff = 0}
fun isempty (Simple {front = [], ...}) = true
| isempty _ = false
fun size (Simple {rear, diff, ...}) =
2 * length rear + diff
| size (Copy1 {rear,diff,copy,f,r,...}) =
2 * length rear + diff + copy + length f + length r
| size (Copy2 {rear,diff,copy,...}) =
2 * length rear + diff + copy
fun insert (x, Simple {front, rear, diff = 0}) =
tick2 (rotate (front, x::rear))
| insert (x, Simple { front, rear, diff }) =
Simple { front = front, rear = x::rear, diff = diff - 1 }
| insert (x, Copy1 { oldfront, rear, f, r, frev, rrev, diff, copy }) =
tick2 (Copy1 { oldfront = oldfront
, rear = x::rear
, f = f
, r = r
, frev = frev
, rrev = rrev
, diff = diff-1
, copy = copy })
| insert (x, Copy2 {oldfront, rear, frev, newfront, diff, copy}) =
tick2 (Copy2 { oldfront = oldfront
, rear = x::rear
, frev = frev
, newfront = newfront
, diff = diff - 1
, copy = copy})
fun remove (Simple {front = [], ...}) = raise Empty
| remove (Simple {front = x::front, rear, diff = 0}) =
(x, tick2 (rotate (front, rear)))
| remove (Simple {front = x::front, rear, diff}) =
(x, Simple {front = front, rear = rear, diff = diff - 1})
| remove (Copy1 {oldfront = x::oldfront, rear, f, r, frev, rrev, diff, copy})=
(x, tick2 (Copy1 { oldfront = oldfront
, rear = rear
, f = f
, r = r
, frev = frev
, rrev = rrev
, diff = diff
, copy = copy - 1 } ) )
| remove (Copy2 {oldfront=x::oldfront,rear,frev,newfront,diff,copy})=
(x, tick2 (Copy2 { oldfront = oldfront
, rear = rear
, frev = frev
, newfront = newfront
, diff = diff
, copy = copy - 1 } ) )
exception InsertfNotSupported
fun insertf (_,_) = raise InsertfNotSupported
end
1 | (* Chris Okasaki |
2 | School of Computer Science |
3 | Carnegie Mellon University |
4 | Pittsburgh, PA 15213 |
5 | cokasaki@cs.cmu.edu *) |
6 | |
7 | functor HoodMelvilleQueue () : QUEUE = |
8 | (* Alternative implementation of queues with O(1) worst-case *) |
9 | (* performance. Provided for comparison. *) |
10 | (* *) |
11 | (* Taken from *) |
12 | (* Hood and Melville *) |
13 | (* "Real-time queue operations in pure Lisp" *) |
14 | (* IPL 13(2) (Nov 1981), 50-53 *) |
15 | (* *) |
16 | (* Warning! Does not support insertf! *) |
17 | struct |
18 | |
19 | datatype 'a Queue = |
20 | Simple of |
21 | {front : 'a list, |
22 | rear : 'a list, |
23 | diff : int} (* diff = length front - length rear *) |
24 | |
25 | | Copy1 of (* in process of reversing f and r *) |
26 | { oldfront : 'a list, |
27 | rear : 'a list, |
28 | f : 'a list, |
29 | r : 'a list, |
30 | frev : 'a list, |
31 | rrev : 'a list, (* the partial new front *) |
32 | diff : int, (* diff = length rrev - length rear *) |
33 | copy : int} (* copy = # of valid elements in frev *) |
34 | |
35 | | Copy2 of (* in process of reversing frev onto newfront *) |
36 | { oldfront : 'a list, |
37 | rear : 'a list, |
38 | frev : 'a list, |
39 | newfront : 'a list, |
40 | diff : int, (* diff = length newfront - length rear *) |
41 | copy : int} (* copy = # of valid elements in frev *) |
42 | |
43 | |
44 | (* begin process of moving elements from rear to front *) |
45 | fun rotate (front,rear) = (* length rear = length front + 1 *) |
46 | Copy1 { oldfront = front |
47 | , rear = [] |
48 | , f = front |
49 | , r = rear |
50 | , frev = [] |
51 | , rrev = [] |
52 | , diff = 0 |
53 | , copy = 0 } |
54 | |
55 | (* do one step in process of moving elements from rear to front *) |
56 | fun tick (Copy1 {oldfront, rear, f=x::f, r=y::r, frev, rrev, diff, copy}) = |
57 | Copy1 { oldfront = oldfront |
58 | , rear = rear |
59 | , f = f |
60 | , r = r |
61 | , frev = x::frev |
62 | , rrev = y::rrev |
63 | , diff = diff + 1 |
64 | , copy = copy + 1 } |
65 | | tick (Copy1 {oldfront, rear, f=[], r=[y], frev, rrev, diff, copy}) = |
66 | Copy2 { oldfront = oldfront |
67 | , rear = rear |
68 | , frev = frev |
69 | , newfront = y::rrev |
70 | , diff = diff + 1 |
71 | , copy = copy } |
72 | | tick (Copy2 {oldfront, rear, newfront, diff, copy = 0, frev}) = |
73 | Simple { front = newfront |
74 | , rear = rear |
75 | , diff = diff |
76 | } |
77 | | tick (Copy2 {oldfront, rear, newfront, diff, copy = 1, frev = x::_}) = |
78 | Simple { front = x::newfront |
79 | , rear = rear |
80 | , diff = diff + 1 |
81 | } |
82 | | tick (Copy2 {oldfront, rear, newfront, diff, copy, frev = x::frev}) = |
83 | Copy2 { oldfront = oldfront |
84 | , rear = rear |
85 | , newfront = x::newfront |
86 | , frev = frev |
87 | , diff = diff + 1 |
88 | , copy = copy - 1 } |
89 | | tick simpleq = simpleq |
90 | |
91 | fun tick2 q = tick (tick q) |
92 | |
93 | |
94 | exception Empty |
95 | |
96 | val empty = Simple {front = [], rear = [], diff = 0} |
97 | |
98 | fun isempty (Simple {front = [], ...}) = true |
99 | | isempty _ = false |
100 | |
101 | fun size (Simple {rear, diff, ...}) = |
102 | 2 * length rear + diff |
103 | | size (Copy1 {rear,diff,copy,f,r,...}) = |
104 | 2 * length rear + diff + copy + length f + length r |
105 | | size (Copy2 {rear,diff,copy,...}) = |
106 | 2 * length rear + diff + copy |
107 | |
108 | fun insert (x, Simple {front, rear, diff = 0}) = |
109 | tick2 (rotate (front, x::rear)) |
110 | | insert (x, Simple { front, rear, diff }) = |
111 | Simple { front = front, rear = x::rear, diff = diff - 1 } |
112 | | insert (x, Copy1 { oldfront, rear, f, r, frev, rrev, diff, copy }) = |
113 | tick2 (Copy1 { oldfront = oldfront |
114 | , rear = x::rear |
115 | , f = f |
116 | , r = r |
117 | , frev = frev |
118 | , rrev = rrev |
119 | , diff = diff-1 |
120 | , copy = copy }) |
121 | | insert (x, Copy2 {oldfront, rear, frev, newfront, diff, copy}) = |
122 | tick2 (Copy2 { oldfront = oldfront |
123 | , rear = x::rear |
124 | , frev = frev |
125 | , newfront = newfront |
126 | , diff = diff - 1 |
127 | , copy = copy}) |
128 | |
129 | fun remove (Simple {front = [], ...}) = raise Empty |
130 | | remove (Simple {front = x::front, rear, diff = 0}) = |
131 | (x, tick2 (rotate (front, rear))) |
132 | | remove (Simple {front = x::front, rear, diff}) = |
133 | (x, Simple {front = front, rear = rear, diff = diff - 1}) |
134 | | remove (Copy1 {oldfront = x::oldfront, rear, f, r, frev, rrev, diff, copy})= |
135 | (x, tick2 (Copy1 { oldfront = oldfront |
136 | , rear = rear |
137 | , f = f |
138 | , r = r |
139 | , frev = frev |
140 | , rrev = rrev |
141 | , diff = diff |
142 | , copy = copy - 1 } ) ) |
143 | | remove (Copy2 {oldfront=x::oldfront,rear,frev,newfront,diff,copy})= |
144 | (x, tick2 (Copy2 { oldfront = oldfront |
145 | , rear = rear |
146 | , frev = frev |
147 | , newfront = newfront |
148 | , diff = diff |
149 | , copy = copy - 1 } ) ) |
150 | |
151 | exception InsertfNotSupported |
152 | fun insertf (_,_) = raise InsertfNotSupported |
153 | end |
154 |