open Okasaki
open OrderedSig
open HeapSig
module SplayHeap (Element : Ordered) : Heap =
struct
module Element = Element
type heaps = Empty | Node of heaps * Element.t * heaps
type heap = heaps
let empty = Empty
let is_empty = function
| Empty -> true
| _ -> false
let rec partition pivot = function
| Empty -> Empty, Empty
| Node (a, x, b) as t ->
if Element.leq x pivot then
match b with
| Empty -> t, Empty
| Node (b1, y, b2) ->
if Element.leq y pivot then
let small, big = partition pivot b2 in
Node (Node (a, x, b1), y, small), big
else
let small, big = partition pivot b1 in
Node (a, x, small), Node (big, y, b2)
else
match a with
| Empty -> Empty, t
| Node (a1, y, a2) ->
if Element.leq y pivot then
let small, big = partition pivot a2 in
Node (a1, y, small), Node (big, x, b)
else
let small, big = partition pivot a1 in
small, Node (big, y, Node (a2, x, b))
let insert x t =
let a, b = partition x t in
Node (a, x, b)
let rec merge h1 h2 =
match h1, h2 with
| Empty, _ -> h2
| Node (a, x, b), _ ->
let ta, tb = partition x h2 in
Node (merge ta a, x, merge tb b)
let rec find_min = function
| Empty -> raise EmptyStructure
| Node (Empty, x, b) -> x
| Node (a, x, b) -> find_min a
let rec delete_min = function
| Empty -> raise EmptyStructure
| Node (Empty, x, b) -> b
| Node (Node (Empty, x, b), y, c) -> Node (b, y, c)
| Node (Node (a, x, b), y, c) -> Node (delete_min a, x, Node (b, y, c))
end
|