chp3.ml

changeset 13
330eff97ead2
child 18
371533fbec14
     1.1 new file mode 100644
     1.2 --- /dev/null
     1.3 +++ b/chp3.ml
     1.4 @@ -0,0 +1,181 @@
     1.5 +(*
     1.6 +   Original source code in SML from:
     1.7 +
     1.8 +     Purely Functional Data Structures
     1.9 +     Chris Okasaki
    1.10 +     Cambridge University Press, 1998
    1.11 +     Copyright (c) 1998 Cambridge University Press
    1.12 +
    1.13 +   Translation from SML to OCAML (this file):
    1.14 +
    1.15 +     Copyright (C) 1999, 2000, 2001  Markus Mottl
    1.16 +     email:  markus.mottl@gmail.com
    1.17 +     www:    http://www.ocaml.info
    1.18 +
    1.19 +   Unless this violates copyrights of the original sources, the following
    1.20 +   licence applies to this file:
    1.21 +
    1.22 +   This source code is free software; you can redistribute it and/or
    1.23 +   modify it without any restrictions. It is distributed in the hope
    1.24 +   that it will be useful, but WITHOUT ANY WARRANTY.
    1.25 +*)
    1.26 +
    1.27 +(***********************************************************************)
    1.28 +(*                              Chapter 3                              *)
    1.29 +(***********************************************************************)
    1.30 +
    1.31 +exception Empty
    1.32 +exception Impossible_pattern of string
    1.33 +
    1.34 +let impossible_pat x = raise (Impossible_pattern x)
    1.35 +
    1.36 +
    1.37 +(* A totally ordered type and its comparison functions *)
    1.38 +module type ORDERED = sig
    1.39 +  type t
    1.40 +
    1.41 +  val eq : t -> t -> bool
    1.42 +  val lt : t -> t -> bool
    1.43 +  val leq : t -> t -> bool
    1.44 +end
    1.45 +
    1.46 +
    1.47 +module type HEAP = sig
    1.48 +  module Elem : ORDERED
    1.49 +
    1.50 +  type heap
    1.51 +
    1.52 +  val empty : heap
    1.53 +  val is_empty : heap -> bool
    1.54 +
    1.55 +  val insert : Elem.t -> heap -> heap
    1.56 +  val merge : heap -> heap -> heap
    1.57 +
    1.58 +  val find_min : heap -> Elem.t  (* raises Empty if heap is empty *)
    1.59 +  val delete_min : heap -> heap  (* raises Empty if heap is empty *)
    1.60 +end
    1.61 +
    1.62 +
    1.63 +module LeftistHeap (Element : ORDERED) : (HEAP with module Elem = Element) =
    1.64 +struct
    1.65 +  module Elem = Element
    1.66 +
    1.67 +  type heap = E | T of int * Elem.t * heap * heap
    1.68 +
    1.69 +  let rank = function E -> 0 | T (r,_,_,_) -> r
    1.70 +
    1.71 +  let makeT x a b =
    1.72 +    if rank a >= rank b then T (rank b + 1, x, a, b)
    1.73 +    else T (rank a + 1, x, b, a)
    1.74 +
    1.75 +  let empty = E
    1.76 +  let is_empty h = h = E
    1.77 +
    1.78 +  let rec merge h1 h2 = match h1, h2 with
    1.79 +    | _, E -> h1
    1.80 +    | E, _ -> h2
    1.81 +    | T (_, x, a1, b1), T (_, y, a2, b2) ->
    1.82 +        if Elem.leq x y then makeT x a1 (merge b1 h2)
    1.83 +        else makeT y a2 (merge h1 b2)
    1.84 +
    1.85 +  let insert x h = merge (T (1, x, E, E)) h
    1.86 +  let find_min = function E -> raise Empty | T (_, x, _, _) -> x
    1.87 +  let delete_min = function E -> raise Empty | T (_, x, a, b) -> merge a b
    1.88 +end
    1.89 +
    1.90 +
    1.91 +module BinomialHeap (Element : ORDERED) : (HEAP with module Elem = Element) =
    1.92 +struct
    1.93 +  module Elem = Element
    1.94 +
    1.95 +  type tree = Node of int * Elem.t * tree list
    1.96 +  type heap = tree list
    1.97 +
    1.98 +  let empty = []
    1.99 +  let is_empty ts = ts = []
   1.100 +
   1.101 +  let rank (Node (r, _, _)) = r
   1.102 +  let root (Node (_, x, _)) = x
   1.103 +
   1.104 +  let link (Node (r, x1, c1) as t1) (Node (_, x2, c2) as t2) =
   1.105 +    if Elem.leq x1 x2 then Node (r + 1, x1, t2 :: c1)
   1.106 +    else Node (r + 1, x2, t1 :: c2)
   1.107 +
   1.108 +  let rec ins_tree t = function
   1.109 +    | [] -> [t]
   1.110 +    | t' :: ts' as ts ->
   1.111 +        if rank t < rank t' then t :: ts
   1.112 +        else ins_tree (link t t') ts'
   1.113 +
   1.114 +  let insert x ts = ins_tree (Node (0, x, [])) ts
   1.115 +
   1.116 +  let rec merge ts1 ts2 = match ts1, ts2 with
   1.117 +    | _, [] -> ts1
   1.118 +    | [], _ -> ts2
   1.119 +    | t1 :: ts1', t2 :: ts2' ->
   1.120 +        if rank t1 < rank t2 then t1 :: merge ts1' ts2
   1.121 +        else if rank t2 < rank t1 then t2 :: merge ts1 ts2'
   1.122 +        else ins_tree (link t1 t2) (merge ts1' ts2')
   1.123 +
   1.124 +  let rec remove_min_tree = function
   1.125 +    | [] -> raise Empty
   1.126 +    | [t] -> t, []
   1.127 +    | t :: ts ->
   1.128 +        let t', ts' = remove_min_tree ts in
   1.129 +        if Elem.leq (root t) (root t') then (t, ts)
   1.130 +        else (t', t :: ts')
   1.131 +
   1.132 +  let find_min ts = root (fst (remove_min_tree ts))
   1.133 +
   1.134 +  let delete_min ts =
   1.135 +    let Node (_, x, ts1), ts2 = remove_min_tree ts in
   1.136 +    merge (List.rev ts1) ts2
   1.137 +end
   1.138 +
   1.139 +
   1.140 +module type SET = sig
   1.141 +  type elem
   1.142 +  type set
   1.143 +
   1.144 +  val empty : set
   1.145 +  val insert : elem -> set -> set
   1.146 +  val member : elem -> set -> bool
   1.147 +end
   1.148 +
   1.149 +
   1.150 +module RedBlackSet (Element : ORDERED) : (SET with type elem = Element.t) =
   1.151 +struct
   1.152 +  type elem = Element.t
   1.153 +
   1.154 +  type color = R | B
   1.155 +  type tree = E | T of color * tree * elem * tree
   1.156 +  type set = tree
   1.157 +
   1.158 +  let empty = E
   1.159 +
   1.160 +  let rec member x = function
   1.161 +    | E -> false
   1.162 +    | T (_, a, y, b) ->
   1.163 +        if Element.lt x y then member x a
   1.164 +        else if Element.lt y x then member x b
   1.165 +        else true
   1.166 +
   1.167 +  let balance = function
   1.168 +    | B, T (R, T (R, a, x, b), y, c), z, d
   1.169 +    | B, T (R, a, x, T (R, b, y, c)), z, d
   1.170 +    | B, a, x, T (R, T (R, b, y, c), z, d)
   1.171 +    | B, a, x, T (R, b, y, T (R, c, z, d)) ->
   1.172 +        T (R, T (B, a, x, b), y, T (B, c, z, d))
   1.173 +    | a, b, c, d -> T (a, b, c, d)
   1.174 +
   1.175 +  let insert x s =
   1.176 +    let rec ins = function
   1.177 +      | E -> T (R, E, x, E)
   1.178 +      | T (color, a, y, b) as s ->
   1.179 +          if Element.lt x y then balance (color, ins a, y, b)
   1.180 +          else if Element.lt y x then balance (color, a, y, ins b)
   1.181 +          else s in
   1.182 +    match ins s with  (* guaranteed to be non-empty *)
   1.183 +    | T (_, a, y, b) -> T (B, a, y, b)
   1.184 +    | _ -> impossible_pat "insert"
   1.185 +end

mercurial