queue.ml
· 5.9 KiB · OCaml
Surowy
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 |