complete lab05
This commit is contained in:
3 files changed
+202
No files matched your search
@@ -0,0 +1,140 @@
|
|||||||
|
module type OrderedType = sig
|
||||||
|
type t
|
||||||
|
val compare : t -> t -> int
|
||||||
|
end
|
||||||
|
|
||||||
|
module type S = sig
|
||||||
|
type k
|
||||||
|
type ('k, 'v) t
|
||||||
|
exception Not_found
|
||||||
|
|
||||||
|
val empty : (k, 'v) t
|
||||||
|
val is_empty : (k, 'v) t -> bool
|
||||||
|
val insert : k -> 'v -> (k, 'v) t -> (k, 'v) t
|
||||||
|
val find_opt : k -> (k, 'v) t -> 'v option
|
||||||
|
val delete : k -> (k, 'v) t -> (k, 'v) t
|
||||||
|
val of_list : (k * 'v) list -> (k, 'v) t
|
||||||
|
val size : (k, 'v) t -> int
|
||||||
|
val find : k -> (k, 'v) t -> 'v
|
||||||
|
val to_list : (k, 'v) t -> (k * 'v) list
|
||||||
|
val to_string : ((k * 'v) -> string) -> (k, 'v) t -> string
|
||||||
|
end
|
||||||
|
|
||||||
|
module Make(Ord: OrderedType) = struct
|
||||||
|
(** [k] is the key of a key-value pair *)
|
||||||
|
type k = Ord.t
|
||||||
|
|
||||||
|
(** [t] is a key-value tree where each N has a key, value, left and right *)
|
||||||
|
type ('k, 'v) t = L | N of k * 'v * (k, 'v) t * (k, 'v) t;;
|
||||||
|
|
||||||
|
(** [Not_found] exception if a given key cannot be found in the tree *)
|
||||||
|
exception Not_found;;
|
||||||
|
|
||||||
|
(** empty tree *)
|
||||||
|
let empty = L;;
|
||||||
|
|
||||||
|
(** [is_empty t] takes a kvtree [t] and checks if it is empty or not *)
|
||||||
|
let is_empty t = t = L;;
|
||||||
|
|
||||||
|
(** [insert k v t] takes a comparator [], key [k], value [v],
|
||||||
|
* and a kvtree [t] to insert the key and value [k, v] into the tree [t]. *)
|
||||||
|
let rec insert k v t =
|
||||||
|
match t with
|
||||||
|
| L -> N (k, v, L, L)
|
||||||
|
| N (k', v', l, r) when Ord.compare k k' < 0 ->
|
||||||
|
N (k', v', insert k v l, r)
|
||||||
|
| N (k', v', l, r) when Ord.compare k k' > 0 ->
|
||||||
|
N (k', v', l, insert k v r)
|
||||||
|
| _ -> t;;
|
||||||
|
|
||||||
|
(** [find_opt k t] takes a key [k] and a kvtree [t] and returns
|
||||||
|
* an Optional value found from the given key [k]. *)
|
||||||
|
let rec find_opt k t =
|
||||||
|
match t with
|
||||||
|
| L -> None
|
||||||
|
| N (k', _, l, _) when Ord.compare k k' < 0 ->
|
||||||
|
find_opt k l
|
||||||
|
| N (k', _, _, r) when Ord.compare k k' > 0 ->
|
||||||
|
find_opt k r
|
||||||
|
| N (_, v, _, _) -> Some v;;
|
||||||
|
|
||||||
|
(** [largest t] finds the largest key in a given kvtree [t]
|
||||||
|
* and retursn the key value pair [k, v] *)
|
||||||
|
let rec largest t =
|
||||||
|
match t with
|
||||||
|
| L -> failwith "largest: empty tree"
|
||||||
|
| N (k, v, _, L) -> (k, v)
|
||||||
|
| N (_, _, _, r) -> largest r;;
|
||||||
|
|
||||||
|
(** [smallest t] finds the smallest key in a given kvtree [t]
|
||||||
|
* and retursn the key value pair [k, v] *)
|
||||||
|
let rec smallest t =
|
||||||
|
match t with
|
||||||
|
| L -> failwith "smallest: empty tree"
|
||||||
|
| N (k, v, L, _) -> (k, v)
|
||||||
|
| N (_, _, l, _) -> smallest l;;
|
||||||
|
|
||||||
|
(** [delete k t] takes a key [k] and deletes it from a given
|
||||||
|
* kvtree [t]. *)
|
||||||
|
let rec delete k t =
|
||||||
|
match t with
|
||||||
|
| L -> L
|
||||||
|
| N (k', v, l, r) when Ord.compare k k' < 0 ->
|
||||||
|
N (k', v, delete k l, r)
|
||||||
|
| N (k', v, l, r) when Ord.compare k k' > 0 ->
|
||||||
|
N (k', v, l, delete k r)
|
||||||
|
| N (_, _, l, L) -> l
|
||||||
|
| N (_, _, L, r) -> r
|
||||||
|
| N (_, _, l, r) ->
|
||||||
|
let (ks, vs) = largest l in
|
||||||
|
N (ks, vs, delete ks l, r);;
|
||||||
|
|
||||||
|
(** [of_list l] takes a list of pairs [l] and creates a
|
||||||
|
* kvtree in the order specefied by the comparator [] to compare
|
||||||
|
* keys *)
|
||||||
|
let of_list l =
|
||||||
|
List.fold_left (fun acc (k, v) -> insert k v acc) L l;;
|
||||||
|
|
||||||
|
(** [size t] takes a kvtree [t] and returns the size of the tree
|
||||||
|
* i.e. number of Ns *)
|
||||||
|
let rec size t =
|
||||||
|
match t with
|
||||||
|
| L -> 0
|
||||||
|
| N (_, _, l, r) ->
|
||||||
|
1 + size l + size r;;
|
||||||
|
|
||||||
|
(** [find k t] takes a key [k] and a kvtree [t] and returns
|
||||||
|
* a value found from the given key [k]. *)
|
||||||
|
let rec find k t =
|
||||||
|
match t with
|
||||||
|
| L -> raise Not_found
|
||||||
|
| N (k', _, l, _) when Ord.compare k k' < 0 ->
|
||||||
|
find k l
|
||||||
|
| N (k', _, _, r) when Ord.compare k k' > 0 ->
|
||||||
|
find k r
|
||||||
|
| N (_, v, _, _) -> v;;
|
||||||
|
|
||||||
|
(** [to_list t] takes a key-value tree [t] and returns
|
||||||
|
* a list representation of the key-value pairs *)
|
||||||
|
let to_list t =
|
||||||
|
let rec aux acc t =
|
||||||
|
match t with
|
||||||
|
| L -> acc
|
||||||
|
| N (k, v, l, r) ->
|
||||||
|
aux ((k, v) :: (aux acc r)) l
|
||||||
|
in
|
||||||
|
aux [] t;;
|
||||||
|
|
||||||
|
(** [to_string f t] takes a function [f] to "convert" a
|
||||||
|
* key-value pair to a string, and applies that to all
|
||||||
|
* key-value pairs in a given tree [t]. *)
|
||||||
|
let to_string f t =
|
||||||
|
let rec aux acc t =
|
||||||
|
match t with
|
||||||
|
| L -> "#"
|
||||||
|
| N (k, v, l, r) ->
|
||||||
|
Printf.sprintf "^(%s, %s, %s)" (f (k, v)) (aux acc l) (aux acc r)
|
||||||
|
in
|
||||||
|
aux "" t;;
|
||||||
|
|
||||||
|
end
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
module type OrderedType = sig
|
||||||
|
type t
|
||||||
|
val compare : t -> t -> int
|
||||||
|
end
|
||||||
|
|
||||||
|
module type S = sig
|
||||||
|
type k
|
||||||
|
type ('k, 'v) t
|
||||||
|
exception Not_found
|
||||||
|
|
||||||
|
val empty : (k, 'v) t
|
||||||
|
val is_empty : (k, 'v) t -> bool
|
||||||
|
val insert : k -> 'v -> (k, 'v) t -> (k, 'v) t
|
||||||
|
val find_opt : k -> (k, 'v) t -> 'v option
|
||||||
|
val delete : k -> (k, 'v) t -> (k, 'v) t
|
||||||
|
val of_list : (k * 'v) list -> (k, 'v) t
|
||||||
|
val size : (k, 'v) t -> int
|
||||||
|
val find : k -> (k, 'v) t -> 'v
|
||||||
|
val to_list : (k, 'v) t -> (k * 'v) list
|
||||||
|
val to_string : ((k * 'v) -> string) -> (k, 'v) t -> string
|
||||||
|
end
|
||||||
|
|
||||||
|
module Make(Ord: OrderedType) : S with type k = Ord.t
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
(* This is a minimal test file. Your program must pass these tests in order
|
||||||
|
to get any credit for your work.
|
||||||
|
In utop:
|
||||||
|
#directory "_build";;
|
||||||
|
#load "kvtree.cmo";;
|
||||||
|
#use "tests.ml";;
|
||||||
|
run ();;
|
||||||
|
*)
|
||||||
|
module M = Kvtree.Make(Int);;
|
||||||
|
|
||||||
|
let t = M.of_list [(3, "three"); (2, "two"); (7, "seven"); (6, "six"); (8, "eight")]
|
||||||
|
let l = [(2, "two"); (3, "three"); (6, "six"); (7, "seven"); (8, "eight")]
|
||||||
|
let s =
|
||||||
|
"^(3, three, ^(2, two, #, #), ^(7, seven, ^(6, six, #, #), ^(8, eight, #, #)))"
|
||||||
|
|
||||||
|
let t2 = M.of_list [(3, 'a')]
|
||||||
|
let s2 = "^(3, a, #, #)"
|
||||||
|
|
||||||
|
let t3 = M.insert 2 'b' t2
|
||||||
|
let s3 = "^(3, a, ^(2, b, #, #), #)"
|
||||||
|
|
||||||
|
let t4 = M.of_list [(3, "3"); (7, "7"); (5, "5"); (6, "6"); (8, "8"); (9, "9")]
|
||||||
|
let s4 = "^(3, 3, #, ^(7, 7, ^(5, 5, #, ^(6, 6, #, #)), ^(8, 8, #, ^(9, 9, #, #))))"
|
||||||
|
let t5 = M.delete 7 t4
|
||||||
|
let s5a = "^(3, 3, #, ^(6, 6, ^(5, 5, #, #), ^(8, 8, #, ^(9, 9, #, #))))"
|
||||||
|
let s5b = "^(3, 3, #, ^(8, 8, ^(5, 5, #, ^(6, 6, #, #)), ^(9, 9, #, #)))"
|
||||||
|
|
||||||
|
let run () =
|
||||||
|
assert (M.size t = 5);
|
||||||
|
assert (M.find 7 t = "seven");
|
||||||
|
assert (M.find_opt 7 t = Some "seven");
|
||||||
|
assert (M.to_list t = l);
|
||||||
|
assert (M.to_string (fun (k, v) -> Printf.sprintf "%d, %s" k v) t = s);
|
||||||
|
assert (M.to_string (fun (k, v) -> Printf.sprintf "%d, %c" k v) t2 = s2);
|
||||||
|
assert (M.to_string (fun (k, v) -> Printf.sprintf "%d, %c" k v) t3 = s3);
|
||||||
|
assert (M.to_string (fun (k, v) -> Printf.sprintf "%d, %s" k v) t4 = s4);
|
||||||
|
assert (
|
||||||
|
let s = M.to_string (fun (k, v) -> Printf.sprintf "%d, %s" k v) t5 in
|
||||||
|
s = s5a || s = s5b)
|
||||||
Reference in new issue
Block a user