Última atividade 1749348107

Revisão e5441afc7fba0f0d3075abec85d9489a5e8befc2

queue.ml Bruto Playground
1(* Chris Okasaki
2 School of Computer Science
3 Carnegie Mellon University
4 Pittsburgh, PA 15213
5 cokasaki@cs.cmu.edu *)
6
7functor 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! *)
17struct
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
153end
154