queue.ml
· 5.9 KiB · OCaml
Исходник
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 | (* begin process of moving elements from rear to front *) |
44 | fun rotate (front,rear) = (* length rear = length front + 1 *) |
45 | Copy1 { oldfront = front |
46 | , rear = [] |
47 | , f = front |
48 | , r = rear |
49 | , frev = [] |
50 | , rrev = [] |
51 | , diff = 0 |
52 | , copy = 0 } |
53 | |
54 | (* do one step in process of moving elements from rear to front *) |
55 | fun tick (Copy1 {oldfront, rear, f=x::f, r=y::r, frev, rrev, diff, copy}) = |
56 | Copy1 { oldfront = oldfront |
57 | , rear = rear |
58 | , f = f |
59 | , r = r |
60 | , frev = x::frev |
61 | , rrev = y::rrev |
62 | , diff = diff + 1 |
63 | , copy = copy + 1 } |
64 | | tick (Copy1 {oldfront, rear, f=[], r=[y], frev, rrev, diff, copy}) = |
65 | Copy2 { oldfront = oldfront |
66 | , rear = rear |
67 | , frev = frev |
68 | , newfront = y::rrev |
69 | , diff = diff + 1 |
70 | , copy = copy } |
71 | | tick (Copy2 {oldfront, rear, newfront, diff, copy = 0, frev}) = |
72 | Simple { front = newfront |
73 | , rear = rear |
74 | , diff = diff |
75 | } |
76 | | tick (Copy2 {oldfront, rear, newfront, diff, copy = 1, frev = x::_}) = |
77 | Simple { front = x::newfront |
78 | , rear = rear |
79 | , diff = diff + 1 |
80 | } |
81 | | tick (Copy2 {oldfront, rear, newfront, diff, copy, frev = x::frev}) = |
82 | Copy2 { oldfront = oldfront |
83 | , rear = rear |
84 | , newfront = x::newfront |
85 | , frev = frev |
86 | , diff = diff + 1 |
87 | , copy = copy - 1 } |
88 | | tick simpleq = simpleq |
89 | |
90 | fun tick2 q = tick (tick q) |
91 | |
92 | |
93 | exception Empty |
94 | |
95 | val empty = Simple {front = [], rear = [], diff = 0} |
96 | |
97 | fun isempty (Simple {front = [], ...}) = true |
98 | | isempty _ = false |
99 | |
100 | fun size (Simple {rear, diff, ...}) = |
101 | 2 * length rear + diff |
102 | | size (Copy1 {rear,diff,copy,f,r,...}) = |
103 | 2 * length rear + diff + copy + length f + length r |
104 | | size (Copy2 {rear,diff,copy,...}) = |
105 | 2 * length rear + diff + copy |
106 | |
107 | fun insert (x, Simple {front, rear, diff = 0}) = |
108 | tick2 (rotate (front, x::rear)) |
109 | | insert (x, Simple { front, rear, diff }) = |
110 | Simple { front = front, rear = x::rear, diff = diff - 1 } |
111 | | insert (x, Copy1 { oldfront, rear, f, r, frev, rrev, diff, copy }) = |
112 | tick2 (Copy1 { oldfront = oldfront |
113 | , rear = x::rear |
114 | , f = f |
115 | , r = r |
116 | , frev = frev |
117 | , rrev = rrev |
118 | , diff = diff-1 |
119 | , copy = copy }) |
120 | | insert (x, Copy2 {oldfront, rear, frev, newfront, diff, copy}) = |
121 | tick2 (Copy2 { oldfront = oldfront |
122 | , rear = x::rear |
123 | , frev = frev |
124 | , newfront = newfront |
125 | , diff = diff - 1 |
126 | , copy = copy}) |
127 | |
128 | fun remove (Simple {front = [], ...}) = raise Empty |
129 | | remove (Simple {front = x::front, rear, diff = 0}) = |
130 | (x, tick2 (rotate (front, rear))) |
131 | | remove (Simple {front = x::front, rear, diff}) = |
132 | (x, Simple {front = front, rear = rear, diff = diff - 1}) |
133 | | remove (Copy1 {oldfront = x::oldfront, rear, f, r, frev, rrev, diff, copy})= |
134 | (x, tick2 (Copy1 { oldfront = oldfront |
135 | , rear = rear |
136 | , f = f |
137 | , r = r |
138 | , frev = frev |
139 | , rrev = rrev |
140 | , diff = diff |
141 | , copy = copy - 1 } ) ) |
142 | | remove (Copy2 {oldfront=x::oldfront,rear,frev,newfront,diff,copy})= |
143 | (x, tick2 (Copy2 { oldfront = oldfront |
144 | , rear = rear |
145 | , frev = frev |
146 | , newfront = newfront |
147 | , diff = diff |
148 | , copy = copy - 1 } ) ) |
149 | |
150 | exception InsertfNotSupported |
151 | fun insertf (_,_) = raise InsertfNotSupported |
152 | end |
153 |