add Heap.remove

This commit is contained in:
Simon Cruanes 2018-02-11 21:52:31 -06:00
parent dd708b1583
commit bc562242c9
2 changed files with 24 additions and 17 deletions

View file

@ -29,7 +29,7 @@ module Make(Elt : RANKED) = struct
*) *)
(* [elt] is above or at its expected position. Move it up the heap (* [elt] is above or at its expected position. Move it up the heap
(towards high indices) to restore the heap property *) (towards the root) to restore the heap property *)
let percolate_up {heap} (elt:Elt.t) : unit = let percolate_up {heap} (elt:Elt.t) : unit =
let pi = ref (parent (Elt.idx elt)) in let pi = ref (parent (Elt.idx elt)) in
let i = ref (Elt.idx elt) in let i = ref (Elt.idx elt) in
@ -42,6 +42,8 @@ module Make(Elt : RANKED) = struct
Vec.set heap !i elt; Vec.set heap !i elt;
Elt.set_idx elt !i Elt.set_idx elt !i
(* move [elt] towards the leaves of the heap to restore the heap
property *)
let percolate_down {heap} (elt:Elt.t): unit = let percolate_down {heap} (elt:Elt.t): unit =
let sz = Vec.size heap in let sz = Vec.size heap in
let li = ref (left (Elt.idx elt)) in let li = ref (left (Elt.idx elt)) in
@ -69,7 +71,9 @@ module Make(Elt : RANKED) = struct
let[@inline] in_heap x = Elt.idx x >= 0 let[@inline] in_heap x = Elt.idx x >= 0
let[@inline] decrease s x = assert (in_heap x); percolate_up s x let[@inline] decrease s x =
assert (in_heap x);
percolate_up s x
(* (*
let increase cmp s n = let increase cmp s n =
@ -112,20 +116,6 @@ module Make(Elt : RANKED) = struct
let[@inline] grow_to_at_least s sz = let[@inline] grow_to_at_least s sz =
Vec.grow_to_at_least s.heap sz Vec.grow_to_at_least s.heap sz
(*
let update cmp s n =
assert (heap_property cmp s);
begin
if in_heap s n then
begin
percolate_up cmp s (Vec.get s.indices n);
percolate_down cmp s (Vec.get s.indices n)
end
else insert cmp s n
end;
assert (heap_property cmp s)
*)
let remove_min ({heap} as s) = let remove_min ({heap} as s) =
if Vec.size heap=0 then raise Not_found; if Vec.size heap=0 then raise Not_found;
let x = Vec.get heap 0 in let x = Vec.get heap 0 in
@ -140,4 +130,16 @@ module Make(Elt : RANKED) = struct
); );
x x
let remove ({heap} as s) (elt:elt) : unit =
assert (in_heap elt);
let i = Elt.idx elt in
Vec.fast_remove heap i;
Elt.set_idx elt ~-1;
assert (not (in_heap elt));
(* element put in place of [x] might be too high *)
if Vec.size heap > i then (
percolate_down s (Vec.get heap i);
);
()
end end

View file

@ -19,7 +19,8 @@ module type S = sig
(** Create a heap *) (** Create a heap *)
val decrease : t -> elt -> unit val decrease : t -> elt -> unit
(** [decrease h x] decreases the value associated to [x] within [h] *) (** [decrease h x] decreases the value associated to [x] within [h],
making it closer to the root (so, more prioritary) *)
val in_heap : elt -> bool val in_heap : elt -> bool
@ -46,6 +47,10 @@ module type S = sig
(** Remove and return the integer that has the lowest value from the heap (** Remove and return the integer that has the lowest value from the heap
@raise Not_found if the heap is empty *) @raise Not_found if the heap is empty *)
val remove : t -> elt -> unit
(** Remove element from the heap.
precond: [in_heap elt] *)
val filter : t -> (elt -> bool) -> unit val filter : t -> (elt -> bool) -> unit
(** Filter out values that don't satisfy the predicate *) (** Filter out values that don't satisfy the predicate *)
end end