From: Norman Ramsey <nr@cs.tufts.edu>
To: caml-list@inria.fr
Subject: Re: [Caml-list] Priority queues, reloaded
Date: Fri, 01 Jul 2011 21:49:22 -0400 [thread overview]
Message-ID: <20110702014925.DFB9D601DAF4C@labrador.cs.tufts.edu> (raw)
In-Reply-To: <4E0CAEC3.7010804@gmail.com> (sfid-j-20110630-131704-+2.76-1@multi.osbf.lua)
[-- Attachment #1: Type: text/plain, Size: 435 bytes --]
> Since the previous discussion regarding priority queues pretty much
> concluded that they weren't available in OCaml, could you point to the most
> compact implementation that you know of?
Attached find a transliteration of some Standard ML code I wrote last
summer. The SML was tested; the transliteration is not. But it does
compile, and I've put it under CC BY license: attribution required,
all uses permitted.
Norman
[-- Attachment #2: leftistheap.ml --]
[-- Type: text/plain, Size: 2603 bytes --]
(* Leftist heap (priority queue) by Norman Ramsey *)
(* Copyright 2011, licensed Creative Commons Attribution (BY),
i.e., attribution required, but all uses permitted
*)
module type PQUEUE = sig
type t
type elem
val empty : t
val insert : elem * t -> t
val is_empty : t -> bool
exception Empty
val deletemin : t -> elem * t (* raises Empty *)
val ok : t -> bool (* satisfies invariant *)
val merges : int ref
end
module MkTreePQ (Elem : sig
type t
val compare : t * t -> int
end) :
PQUEUE with type elem = Elem.t
=
struct
type elem = Elem.t
type height = int
type t = EMPTY
| NODE of elem * height * t * t
(* invariant:
elem in a node is not greater than the elems in its nonempty children
left child is at least as high as right child
height represents true height
*)
let le (x1, x2) = Elem.compare (x1, x2) <= 0
let rec height = function
| EMPTY -> 0
| (NODE (_, h, _, _)) -> h
let merges = ref 0
let rec merge = function
| (EMPTY, q) -> q
| (q, EMPTY) -> q
| ((NODE (x1, _, l1, r1) as q1), (NODE (x2, _, _, _) as q2)) ->
if le (x1, x2) then
let (to_merge, to_stand) =
if height l1 > height q2 then (q2, l1) else (l1, q2) in
let newq1 = merge (r1, to_merge) in
let newq2 = to_stand in
let h1 = height newq1 in
let h2 = height newq2 in
let h = max h1 h2 + 1 in
let (l, r) = if h1 > h2 then (newq1, newq2) else (newq2, newq1) in
let _ = merges := !merges + 1 in
NODE (x1, h, l, r)
else
merge (q2, q1)
let empty = EMPTY
let rec insert = function
| (x, EMPTY) -> NODE (x, 1, EMPTY, EMPTY)
| (x, q) -> merge (insert(x, empty), q)
let is_empty = function
| EMPTY -> true
| (NODE _) -> false
exception Empty
let deletemin = function
| EMPTY -> raise Empty
| (NODE (x, _, q, q')) -> (x, merge (q, q'))
let rec ok_h_le h x q =
(* q satisfies invariant, has height h, each elem at least x *)
match q with
| EMPTY -> h = 0
| NODE (x', h', l, r) ->
h = h' && le(x, x') &&
(h = height l + 1 || h = height r + 1) &&
h > height l && h > height r &&
ok_h_le (height l) x' l && ok_h_le (height r) x' r
let ok = function
| EMPTY -> true
| (NODE (x, h, _, _) as q) -> ok_h_le h x q
end
next prev parent reply other threads:[~2011-07-02 1:49 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <sfid-j-20110630-131704-+2.76-1@multi.osbf.lua>
2011-06-30 17:13 ` Andrew
2011-06-30 17:26 ` Gabriel Scherer
2011-06-30 18:14 ` Jean-Christophe Filliâtre
2011-06-30 18:36 ` Jean-Christophe Filliâtre
2011-07-09 9:02 ` Jon Harrop
2011-07-09 19:22 ` Jean-Christophe Filliâtre
2011-07-10 18:04 ` Jon Harrop
2011-06-30 19:13 ` Andrew
2011-06-30 22:17 ` Wojciech Meyer
2011-07-02 1:49 ` Norman Ramsey [this message]
2011-07-09 9:05 ` Jon Harrop
[not found] <848371343.3424870.1309454037170.JavaMail.root@zmbs3.inria.fr>
2011-06-30 18:03 ` Daniel de Rauglaudre
[not found] <fa.V8myB/rA6OKILQg+GW40f8c1BGo@ifi.uio.no>
2011-07-02 12:24 ` Radu Grigore
2011-07-02 19:05 ` Andrew
2011-07-02 22:42 ` Radu Grigore
2011-07-10 17:55 ` Jon Harrop
2011-07-09 18:45 james woodyatt
[not found] ` <14B0DF03-EF83-4568-AB34-6B51BCE4B574@recoil.org>
2011-07-09 18:56 ` james woodyatt
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20110702014925.DFB9D601DAF4C@labrador.cs.tufts.edu \
--to=nr@cs.tufts.edu \
--cc=caml-list@inria.fr \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox