1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
| (** {2 Définition} *)
(** Définition d'un tas *)
type 'a t =
| Empty
| Node of 'a t * 'a * 'a t
(** Comparaison de deux tas *)
let rec compare t1 t2 =
match t1,t2 with
| Empty , Empty -> 0
| Empty , _ -> -1
| Node (Empty,n,Empty) , Node (Empty,k,Empty) -> Pervasives.compare n k
| Node (Empty,n,Empty) , Node (_,k,_) -> Pervasives.compare n k
| Node (_,n,_) , Node (_,k,_) -> Pervasives.compare n k
| _ -> -(compare t2 t1)
(** Opérateurs *)
let (== ) t1 t2 = compare t1 t2 = 0
let (>> ) t1 t2 = compare t1 t2 > 0
let (>>=) t1 t2 = t1 >> t2 || t1 == t2
let (<< ) t1 t2 = not (t2 >>= t1)
let (<<=) t1 t2 = not (t2 >> t1)
(** {2 Opération sur un tas} *)
(** Insérer un objet dans un tas *)
let rec push item heap =
match heap with
| Empty -> Node (Empty,item,Empty)
| Node (Empty,n,Empty) when n > item -> Node (Node (Empty,item,Empty),n,Empty)
| Node (Empty,n,Empty) -> Node (Node (Empty,n,Empty),item,Empty)
| Node (hpl,n,hpr) when n < item -> push n (Node (hpl,item,hpr))
| Node (hpl,n,hpr) when hpl >> hpr -> Node (hpl,n,push item hpr)
| Node (hpl,n,hpr) -> Node (push item hpl,n,hpr)
(** Tête du tas *)
let head = function
| Empty -> raise (Invalid_argument "Heap.head")
| Node (_,n,_) -> n
(** Queue du tas *)
let rec pop = function
| Empty -> Empty
| Node (Empty,_,Empty) -> Empty
| Node (hpl,_,hpr) when hpl >> hpr -> Node(pop hpl,head hpl,hpr)
| Node (_,n,hpr) when hpr == Empty -> Empty
| Node (hpl,_,hpr) -> Node(hpl,head hpr,pop hpr)
(** {2 Interactivité avec les listes} *)
(** Transforme un tas en liste *)
let to_list heap =
let rec f hpl hpr acc =
match hpl,hpr with
| Empty,Empty -> acc
| Empty,Node (Empty,n,Empty) -> n::acc
| Empty,Node (hprl,n,hprr) -> f hprl hprr (n::acc)
| Node (Empty,n,Empty),Node (Empty,k,Empty) when n > k -> f Empty hpr (n::acc)
| Node (Empty,_,Empty),Node (Empty,k,Empty) -> f Empty hpl (k::acc)
| Node (Empty,n,Empty),_ when hpl >> hpr -> f Empty hpr (n::acc)
| Node (Empty,_,Empty),Node (hprl,k,hprr) -> f Empty hpl (k::acc)
| _ when hpl >> hpr -> f (pop hpl) hpr ((head hpl)::acc)
| _ -> f hpr (pop hpl) ((head hpr)::acc)
in
f heap Empty []
(** Transforme une liste en tas trié *)
let of_list lst =
let rec f lst acc =
match lst with
| [] -> acc
| hd::tl -> f tl (push hd acc)
in
f lst Empty
(** Trie une liste via heap sort *)
let list_sort l = to_list (of_list l)
(** Suppression du plus petit élément *)
let remove_min heap =
match to_list heap with
| [] -> Empty
| _::lst -> of_list lst |
Partager