emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/heap 9bcd8d3 16/31: Added heap-build function for effic


From: Stefan Monnier
Subject: [elpa] externals/heap 9bcd8d3 16/31: Added heap-build function for efficiently building a heap out of a vector.
Date: Mon, 14 Dec 2020 12:13:35 -0500 (EST)

branch: externals/heap
commit 9bcd8d3cc6a4ac7a96bd38a11236b0b70956f09f
Author: Toby S. Cubitt <toby-predictive@dr-qubit.org>
Commit: Toby S. Cubitt <toby-predictive@dr-qubit.org>

    Added heap-build function for efficiently building a heap out of a vector.
---
 heap.el | 52 +++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 41 insertions(+), 11 deletions(-)

diff --git a/heap.el b/heap.el
index e862809..403342d 100644
--- a/heap.el
+++ b/heap.el
@@ -67,6 +67,8 @@
 ;; Version 0.3
 ;; * converted heap data structures into defstructs
 ;; * increased default heap size to 16, and default resize-factor to 2
+;; * added `heap-build' function for efficiently building a heap out of
+;;   a vector
 ;;
 ;; Version 0.2.2
 ;; * fixed bug in `heap-copy'
@@ -101,7 +103,7 @@
 
 ;;; Code:
 
-(provide 'heap)
+(eval-when-compile (require 'cl))
 
 
 ;;; ================================================================
@@ -197,6 +199,31 @@ defaulting to 2."
   (heap--create compare-function initial-size resize-factor))
 
 
+(defun heap-build (compare-function vec &optional resize-factor)
+  "Build a heap from vector VEC with COMPARE-FUNCTION
+as the comparison function.
+
+Note that VEC is modified, and becomes part of the heap data
+structure. If you don't want this, copy the vector first and pass
+the copy in VEC.
+
+COMPARE-FUNCTION takes two arguments, A and B, and returns
+non-nil or nil. To implement a max-heap, it should return non-nil
+if A is greater than B. To implemenet a min-heap, it should
+return non-nil if A is less than B.
+
+RESIZE-FACTOR sets the factor by which the heap's size is
+increased if it runs out of space, defaulting to 2."
+  (or resize-factor (setq resize-factor 2))
+  (let ((heap (heap--create compare-function (length vec) resize-factor))
+       (i (ceiling (1- (expt 3
+            (ceiling (1- (log (1+ (* 2 (length vec))) 3))))) 2)))
+    (setf (heap--vect heap) vec
+         (heap--count heap) (length vec))
+    (while (>= (decf i) 0) (heap--sift-down heap i))
+    heap))
+
+
 (defun heap-copy (heap)
  "Return a copy of heap HEAP."
  (let ((newheap (heap--create (heap--cmpfun heap) (heap--size heap)
@@ -250,17 +277,17 @@ defaulting to 2."
 
 (defun heap-delete-root (heap)
   "Return the root of the heap and delete it from the heap."
-  (let (vect root (count (heap--count heap)))
+  (let ((vect (heap--vect heap))
+       root count)
     ;; deal with empty heaps and heaps with just one element
-    (if (= count 0) nil
-      (setq vect (heap--vect heap))
-      (setq root (aref vect 0))
-      (setf (heap--count heap) (1- (heap--count heap)))
-      (if (= 1 count) (setf (heap--vect heap) (make-vector 16 nil))
-       ;; Delete root, swap last element to top, and sift-down from top
-       (setq vect (heap--vect heap))
-       (aset vect 0 (aref vect (1- count)))
-       (aset vect (1- count) nil)
+    (if (= 0 (heap--count heap)) nil
+      (setq root (aref vect 0)
+           count (decf (heap--count heap)))
+      (if (= 0 count)
+         (setf (heap--vect heap) (make-vector 16 nil))
+       ;; delete root, swap last element to top, and sift-down from top
+       (aset vect 0 (aref vect count))
+       (aset vect count nil)
        (heap--sift-down heap 0))
       root)))
 
@@ -295,6 +322,9 @@ Note that only the match highest up the heap is modified."
       nil)))  ; return nil if no match was found
 
 
+
+(provide 'heap)
+
 ;;; Local Variables:
 ;;; fill-column: 72
 ;;; End:



reply via email to

[Prev in Thread] Current Thread [Next in Thread]