Source file lwt_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
module type OrderedType =
sig
type t
val compare: t -> t -> int
end
module type S =
sig
type elt
type t
val empty: t
val is_empty: t -> bool
val add: elt -> t -> t
val union: t -> t -> t
val find_min: t -> elt
val lookup_min: t -> elt option
val remove_min: t -> t
val size: t -> int
end
module Make(Ord: OrderedType) : (S with type elt = Ord.t) =
struct
type elt = Ord.t
type t = tree list
and tree = Node of elt * int * tree list
let root (Node (x, _, _)) = x
let rank (Node (_, r, _)) = r
let link (Node (x1, r1, c1) as t1) (Node (x2, r2, c2) as t2) =
let c = Ord.compare x1 x2 in
if c <= 0 then Node (x1, r1 + 1, t2::c1) else Node(x2, r2 + 1, t1::c2)
let rec ins t =
function
[] ->
[t]
| (t'::_) as ts when rank t < rank t' ->
t::ts
| t'::ts ->
ins (link t t') ts
let empty = []
let is_empty ts = ts = []
let add x ts = ins (Node (x, 0, [])) ts
let rec union ts ts' =
match ts, ts' with
([], _) -> ts'
| (_, []) -> ts
| (t1::ts1, t2::ts2) ->
if rank t1 < rank t2 then t1 :: union ts1 (t2::ts2)
else if rank t2 < rank t1 then t2 :: union (t1::ts1) ts2
else ins (link t1 t2) (union ts1 ts2)
let rec find_min =
function
[] -> raise Not_found
| [t] -> root t
| t::ts ->
let x = find_min ts in
let c = Ord.compare (root t) x in
if c < 0 then root t else x
let rec lookup_min =
function
| [] -> None
| [t] -> Some (root t)
| t::ts ->
match lookup_min ts with
| None -> None
| Some x as result ->
let c = Ord.compare (root t) x in
if c < 0 then Some (root t) else result
let rec get_min =
function
[] -> assert false
| [t] -> (t, [])
| t::ts ->
let (t', ts') = get_min ts in
let c = Ord.compare (root t) (root t') in
if c < 0 then (t, ts) else (t', t::ts')
let remove_min =
function
[] -> raise Not_found
| ts ->
let (Node (_, _, c), ts) = get_min ts in
union (List.rev c) ts
let rec size l =
let sizetree (Node (_,_,tl)) = 1 + size tl in
List.fold_left (fun s t -> s + sizetree t) 0 l
end