Ostatnio aktywny 1749348107

Rewizja 0b3071ce3b4ae2298f6fd2230cff131f2a56a3cf

queue.ml Surowy 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 (* 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
152end
153