From 89f4500fc2efea70b45749012bc4a791c1c8b08e Mon Sep 17 00:00:00 2001 From: Simon Cruanes Date: Fri, 13 Jun 2014 21:51:33 +0200 Subject: [PATCH] updated CCLefistheap (more functions) --- core/CCLeftistheap.ml | 40 +++++++++++++++++++++++++++++++++++++--- core/CCLeftistheap.mli | 35 +++++++++++++++++++++++++---------- 2 files changed, 62 insertions(+), 13 deletions(-) diff --git a/core/CCLeftistheap.ml b/core/CCLeftistheap.ml index 5c6f9def..b0e5fe9f 100644 --- a/core/CCLeftistheap.ml +++ b/core/CCLeftistheap.ml @@ -28,6 +28,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (** Polymorphic implementation, following Okasaki *) type 'a sequence = ('a -> unit) -> unit +type 'a klist = unit -> [`Nil | `Cons of 'a * 'a klist] type 'a t = { tree : 'a tree; @@ -81,6 +82,8 @@ let insert heap x = let tree = merge_tree heap.leq (Node (1, x, Empty, Empty)) heap.tree in { heap with tree; } +let add = insert + let filter heap p = let rec filter tree p = match tree with | Empty -> Empty @@ -104,7 +107,14 @@ let extract_min heap = let heap' = { heap with tree; } in heap', x -let iter heap f = +let take heap = match heap.tree with + | Empty -> None + | Node (_, x, a, b) -> + let tree = merge_tree heap.leq a b in + let heap' = { heap with tree; } in + Some (x, heap') + +let iter f heap = let rec iter t = match t with | Empty -> () | Node (_, x, a, b) -> @@ -113,9 +123,18 @@ let iter heap f = iter b; in iter heap.tree +let fold f acc h = + let rec fold acc h = match h with + | Empty -> acc + | Node (_, x, a, b) -> + let acc = f acc x in + let acc = fold acc a in + fold acc b + in fold acc h.tree + let size heap = let r = ref 0 in - iter heap (fun _ -> incr r); + iter (fun _ -> incr r) heap; !r let of_seq heap seq = @@ -123,4 +142,19 @@ let of_seq heap seq = seq (fun x -> h := insert !h x); !h -let to_seq = iter +let to_seq h k = iter k h + +let rec of_klist h l = match l() with + | `Nil -> h + | `Cons (x, l') -> + let h' = add h x in + of_klist h' l' + +let to_klist h = + let rec next stack () = match stack with + | [] -> `Nil + | Empty :: stack' -> next stack' () + | Node (_, x, a, b) :: stack' -> + `Cons (x, next (a :: b :: stack')) + in + next [h.tree] diff --git a/core/CCLeftistheap.mli b/core/CCLeftistheap.mli index 701df006..aa99a61f 100644 --- a/core/CCLeftistheap.mli +++ b/core/CCLeftistheap.mli @@ -23,11 +23,11 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *) -(** {1 Leftist Heaps} *) - -(** Polymorphic implementation, following Okasaki *) +(** {1 Leftist Heaps} +Polymorphic implementation, following Okasaki *) type 'a sequence = ('a -> unit) -> unit +type 'a klist = unit -> [`Nil | `Cons of 'a * 'a klist] type 'a t (** Heap containing values of type 'a *) @@ -37,7 +37,7 @@ val empty_with : leq:('a -> 'a -> bool) -> 'a t smaller than the second. *) val empty : 'a t - (** Empty heap using Pervasives.compare *) + (** Empty heap using [Pervasives.compare] *) val is_empty : _ t -> bool (** Is the heap empty? *) @@ -48,21 +48,36 @@ val merge : 'a t -> 'a t -> 'a t val insert : 'a t -> 'a -> 'a t (** Insert a value in the heap *) +val add : 'a t -> 'a -> 'a t + (** Synonym to {!insert} *) + val filter : 'a t -> ('a -> bool) -> 'a t - (** Filter values, only retaining the ones that satisfy the predicate *) + (** Filter values, only retaining the ones that satisfy the predicate. + Linear time at least. *) val find_min : 'a t -> 'a - (** Find minimal element, or raise Not_found *) + (** Find minimal element, or fails + @raise Not_found if the heap is empty *) val extract_min : 'a t -> 'a t * 'a - (** Extract and returns the minimal element, or raise Not_found *) + (** Extract and returns the minimal element, or + raise Not_found if the heap is empty *) -val iter : 'a t -> ('a -> unit) -> unit +val take : 'a t -> ('a * 'a t) option + (** Extract and return the minimum element, and the new heap (without + this element), or [None] if the heap is empty *) + +val iter : ('a -> unit) -> 'a t -> unit (** Iterate on elements *) +val fold : ('b -> 'a -> 'b) -> 'b -> 'a t -> 'b + (** Fold on all values *) + val size : _ t -> int - (** Number of elements (linear) *) + (** Number of elements (linear complexity) *) val of_seq : 'a t -> 'a sequence -> 'a t - val to_seq : 'a t -> 'a sequence + +val of_klist : 'a t -> 'a klist -> 'a t +val to_klist : 'a t -> 'a klist