0% found this document useful (0 votes)
18 views3 pages

Bheap ML

The document defines a mutable data structure for a priority queue (tas) in OCaml, including functions for managing elements, resizing arrays, and maintaining heap properties. It also includes a sample graph represented as an adjacency list. The implementation provides methods for inserting elements, decreasing priority, and removing the minimum element.

Uploaded by

coco05 V2
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
18 views3 pages

Bheap ML

The document defines a mutable data structure for a priority queue (tas) in OCaml, including functions for managing elements, resizing arrays, and maintaining heap properties. It also includes a sample graph represented as an adjacency list. The implementation provides methods for inserting elements, decreasing priority, and removing the minimum element.

Uploaded by

coco05 V2
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 3

module Tas = struct

type tas = {
mutable elems : (int * float) option array ;
mutable where : (int option) array;
mutable size : int;
}
let pp_opt p fmt opt =
match opt with
| None -> Format.fprintf fmt "None"
| Some(x) -> Format.fprintf fmt "Some(%a)" p x

let print_tas (t: tas) =


Format.printf "@[<v>@[<v 2>{@,elems: %a@,where: %a@, size: %d@]@,}@]@."
(Format.pp_print_list ~pp_sep:(fun fmt () -> Format.fprintf fmt "; ") (pp_opt
(fun fmt (i, f) -> Format.fprintf fmt "%d, %f" i f))) (t.elems |> Array.to_list)
(Format.pp_print_list ~pp_sep:(fun fmt () -> Format.fprintf fmt "; ") (pp_opt
Format.pp_print_int)) (t.where |> Array.to_list)
t.size

let resize_where_for_i (i: int) (t: tas) =


let n = Array.length t.where in
if i >= n then
let rec aux n = if i < n then n else aux (2 * n) in
let new_alloc = aux n in
let new_where = Array.make (new_alloc) None in
Array.blit t.where 0 new_where 0 n ;
t.where <- new_where

let resize_elems_if_needed (t: tas) =


let n = Array.length t.elems in
if t.size = n then
let new_elems = Array.make (2 * t.size) None in
Array.blit t.elems 0 new_elems 0 t.size ;
t.elems <- new_elems;
else if t.size < n / 2 then
let new_elems = Array.make (n/2) None in
Array.blit t.elems 0 new_elems 0 t.size ;
t.elems <- new_elems

let mem_tas (t: tas) (elem: int) : bool =


elem < (Array.length t.where) && t.where.(elem) != None

let is_empty (t: tas) : bool =


t.size = 0

let get tab i =


match tab.(i) with
| Some (x) -> x
| None -> raise (Invalid_argument "get")
let set tab i x =
tab.(i) <- Some(x)
let get_prio tab i =
snd (get tab i)

let prio_assoc (t: tas) (x: int) : float =


let w = get t.where x in
let _, f = get t.elems w in
f
let swap elems where i j =
let who_is_in_i, i_prio = get elems i in
let who_is_in_j, j_prio = get elems j in
set elems i (who_is_in_j, j_prio);
set elems j (who_is_in_i, i_prio);
where.(who_is_in_i) <- Some (j);
where.(who_is_in_j) <- Some (i)

let cree_tas_vide () = {elems = Array.make 1 None; where = Array.make 1 None;


size = 0}
let elem_min (t: tas) : int = get t.elems 0 |> fst
let prio_min (t: tas) : float = get t.elems 0 |> snd
let elem_prio_min (t: tas) : int * float = get t.elems 0
let has_left_son (t: tas) (i: int) = 2 * i + 1 < t.size
let has_right_son (t: tas) (i: int) = 2 * i + 2 < t.size
let is_root (t: tas) (i: int): bool = i = 0
let left_son (i: int) = 2 * i + 1
let right_son (i: int) = 2 * i + 2
let father (i: int) = (i-1) / 2

exception NotValide
let est_valide (t: tas): bool =
try
for i = 1 to t.size-1 do
if (get t.elems (father i) |> snd) > (get t.elems i |> snd) then raise
NotValide
done;
true
with NotValide -> false

let insere_tas (t: tas) (elem: int) (prio: float) : unit =


resize_where_for_i elem t;
resize_elems_if_needed t;
let elemprio = (elem, prio) in
set t.elems t.size elemprio ;
set t.where (fst elemprio) t.size;
let curs = ref t.size in
t.size <- t.size + 1 ;
while (not (is_root t (!curs)) && (get_prio t.elems (!curs)) < (get_prio
t.elems (father !curs))) do
swap t.elems t.where (!curs) (father !curs);
curs := father (!curs);
done

let decrease_prio (t: tas) (elem : int) (prio : float) : unit =


let w = get t.where elem in
set t.elems w (elem, prio);
let curs = ref w in
while (not (is_root t (!curs)) && (get_prio t.elems (!curs)) < (get_prio
t.elems (father !curs))) do
swap t.elems t.where (!curs) (father !curs);
curs := father (!curs);
done

let supprime_min (t: tas): unit =


let e = elem_min t in
swap t.elems t.where 0 (t.size-1);
t.elems.(t.size-1) <- None;
t.size <- t.size-1;
let curs = ref 0 in
while ((has_left_son t !curs
&& get_prio t.elems (!curs) > get_prio t.elems (left_son !curs))
||(has_right_son t !curs
&& get_prio t.elems (!curs) > get_prio t.elems (right_son !curs))) do
let next = if ((has_right_son t !curs)
&& get_prio t.elems (right_son !curs) < get_prio t.elems
(left_son !curs))
then right_son !curs
else left_son !curs
in
swap t.elems t.where (!curs) next;
curs := next
done;
t.where.(e) <- None;
resize_elems_if_needed t
end

(* par listes d'adjacences *)


type graph = (int * float) list array

let g_ex =
[|
[(1, 3.); (2, 1.); (3, 1.); (6, 2.);];
[(6, 2.); (2, 1.); (4, 2.);];
[(5, 3.); (4, 3.); (7, 4.);];
[(2, 1.); (6, 2.); (8, 5.);];
[(8, 1.); (7, 1.);];
[(4, 3.); (8, 1.); (9, 2.);];
[(5, 2.); (9, 5.);];
[(8, 2.);];
[(6, 1.);];
[(8, 1.);]
|]

You might also like