Source file pqueue.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
module type OrderedPolyType = sig
type 'a t
val compare : 'a t -> 'b t -> int
end
module MakeMinPoly(E: OrderedPolyType) =
struct
type 'a elt = 'a E.t
type 'a t = 'a E.t Dynarray.t
let create =
Dynarray.create
let length =
Dynarray.length
let is_empty =
Dynarray.is_empty
let clear =
Dynarray.clear
let left_child i = 2 * i + 1
let right_child i = 2 * i + 2
let parent_node i = (i - 1) / 2
let rec sift_up h i x =
if i = 0 then Dynarray.set h 0 x else
let p = parent_node i in
let y = Dynarray.get h p in
if E.compare x y < 0 then (
Dynarray.set h i y;
sift_up h p x
) else
Dynarray.set h i x
let add h x =
let i = Dynarray.length h in
Dynarray.add_last h x;
if i > 0 then sift_up h i x
let add_iter h iter x =
iter (add h) x
let min_elt h =
if Dynarray.is_empty h then None else Some (Dynarray.get h 0)
let get_min_elt h =
if Dynarray.is_empty h then invalid_arg "empty priority queue";
Dynarray.get h 0
let lt h i j =
E.compare (Dynarray.get h i) (Dynarray.get h j) < 0
let rec sift_down h ~len i x =
let left = left_child i in
if left >= len then Dynarray.set h i x else
let smallest =
let right = right_child i in
if right >= len then left else
if lt h left right then left else right
in
let y = Dynarray.get h smallest in
if E.compare y x < 0 then (
Dynarray.set h i y;
sift_down h ~len smallest x
) else
Dynarray.set h i x
let pop_min h =
let n = Dynarray.length h in
if n = 0 then None else
let x = Dynarray.pop_last h in
if n = 1 then Some x else (
let r = Dynarray.get h 0 in
sift_down h ~len:(n - 1) 0 x;
Some r
)
let remove_min h =
let n = Dynarray.length h in
if n > 0 then (
let x = Dynarray.pop_last h in
if n > 1 then sift_down h ~len:(n - 1) 0 x
)
let copy =
Dynarray.copy
let heapify h =
let n = Dynarray.length h in
for i = n/2 - 1 downto 0 do
sift_down h ~len:n i (Dynarray.get h i)
done;
h
let of_array a =
Dynarray.of_array a |> heapify
let of_list l =
Dynarray.of_list l |> heapify
let of_iter iter x =
let a = Dynarray.create () in
iter (Dynarray.add_last a) x;
heapify a
let iter_unordered =
Dynarray.iter
let fold_unordered =
Dynarray.fold_left
end
module type MinPoly =
sig
type 'a t
type 'a elt
val create: unit ->'a t
val length: 'a t -> int
val is_empty: 'a t -> bool
val add: 'a t -> 'a elt -> unit
val add_iter: 'a t -> (('a elt -> unit) -> 'x -> unit) -> 'x -> unit
val min_elt: 'a t -> 'a elt option
val get_min_elt: 'a t -> 'a elt
val pop_min: 'a t -> 'a elt option
val remove_min: 'a t -> unit
val clear: 'a t -> unit
val copy: 'a t -> 'a t
val of_array: 'a elt array -> 'a t
val of_list: 'a elt list -> 'a t
val of_iter: (('a elt -> unit) -> 'x -> unit) -> 'x -> 'a t
val iter_unordered: ('a elt -> unit) -> 'a t -> unit
val fold_unordered: ('acc -> 'a elt -> 'acc) -> 'acc -> 'a t -> 'acc
end
module type MaxPoly =
sig
type 'a t
type 'a elt
val create: unit -> 'a t
val length: 'a t -> int
val is_empty: 'a t -> bool
val add: 'a t -> 'a elt -> unit
val add_iter: 'a t -> (('a elt -> unit) -> 'x -> unit) -> 'x -> unit
val max_elt: 'a t -> 'a elt option
val get_max_elt: 'a t -> 'a elt
val pop_max: 'a t -> 'a elt option
val remove_max: 'a t -> unit
val clear: 'a t -> unit
val copy: 'a t -> 'a t
val of_array: 'a elt array -> 'a t
val of_list: 'a elt list -> 'a t
val of_iter: (('a elt -> unit) -> 'x -> unit) -> 'x -> 'a t
val iter_unordered: ('a elt -> unit) -> 'a t -> unit
val fold_unordered: ('acc -> 'a elt -> 'acc) -> 'acc -> 'a t -> 'acc
end
module MakeMaxPoly(E: OrderedPolyType)
: MaxPoly with type 'a elt = 'a E.t =
struct
include MakeMinPoly(struct
type 'a t = 'a E.t
let compare x y = E.compare y x
end)
let max_elt = min_elt
let get_max_elt = get_min_elt
let pop_max = pop_min
let remove_max = remove_min
end
module type OrderedType =
sig
type t
val compare: t -> t -> int
end
module type Min =
sig
type t
type elt
val create: unit ->t
val length: t -> int
val is_empty: t -> bool
val add: t -> elt -> unit
val add_iter: t -> ((elt -> unit) -> 'x -> unit) -> 'x -> unit
val min_elt: t -> elt option
val get_min_elt: t -> elt
val pop_min: t -> elt option
val remove_min: t -> unit
val clear: t -> unit
val copy: t -> t
val of_array: elt array -> t
val of_list: elt list -> t
val of_iter: ((elt -> unit) -> 'x -> unit) -> 'x -> t
val iter_unordered: (elt -> unit) -> t -> unit
val fold_unordered: ('acc -> elt -> 'acc) -> 'acc -> t -> 'acc
end
module MakeMin(E: OrderedType) =
struct
include MakeMinPoly(struct type 'a t = E.t
let compare = E.compare end)
type t = E.t Dynarray.t
end
module type Max =
sig
type t
type elt
val create: unit ->t
val length: t -> int
val is_empty: t -> bool
val add: t -> elt -> unit
val add_iter: t -> ((elt -> unit) -> 'x -> unit) -> 'x -> unit
val max_elt: t -> elt option
val get_max_elt: t -> elt
val pop_max: t -> elt option
val remove_max: t -> unit
val clear: t -> unit
val copy: t -> t
val of_array: elt array -> t
val of_list: elt list -> t
val of_iter: ((elt -> unit) -> 'x -> unit) -> 'x -> t
val iter_unordered: (elt -> unit) -> t -> unit
val fold_unordered: ('acc -> elt -> 'acc) -> 'acc -> t -> 'acc
end
module MakeMax(E: OrderedType) =
struct
include MakeMinPoly(struct type 'a t = E.t
let compare x y = E.compare y x end)
type t = E.t Dynarray.t
let max_elt = min_elt
let get_max_elt = get_min_elt
let pop_max = pop_min
let remove_max = remove_min
end