]> mj.ucw.cz Git - libucw.git/blobdiff - ucw/heap.h
Main: Let main-block use HOOK_RETRY / HOOK_IDLE as suggested by the docs
[libucw.git] / ucw / heap.h
index 4f83776f5cb0dff38dbf646a702b23775926ebed..e0a33b02a60968bd5e0d24003c7b43a3b59c6cfe 100644 (file)
@@ -8,6 +8,40 @@
  *     of the GNU Lesser General Public License.
  */
 
+/***
+ * [[intro]]
+ * Introduction
+ * ------------
+ *
+ * Binary heap is a simple data structure, which for example supports efficient insertions, deletions
+ * and access to the minimal inserted item. We define several macros for such operations.
+ * Note that because of simplicity of heaps, we have decided to define direct macros instead
+ * of a <<generic:,macro generator>> as for several other data structures in the Libucw.
+ *
+ * A heap is represented by a number of elements and by an array of values. Beware that we
+ * index this array from one, not from zero as do the standard C arrays.
+ *
+ * Most macros use these parameters:
+ *
+ * - @type - the type of elements
+ * - @num - a variable (signed or unsigned integer) with the number of elements
+ * - @heap - a C array of type @type; the heap is stored in `heap[1] .. heap[num]`; `heap[0]` is unused
+ * - @less - a callback to compare two element values; `less(x, y)` shall return a non-zero value iff @x is lower than @y
+ * - @swap - a callback to swap two array elements; `swap(heap, i, j, t)` must swap `heap[i]` with `heap[j]` with possible help of temporary variable @t (type @type).
+ *
+ * A valid heap must follow these rules:
+ *
+ * - `num >= 0`
+ * - `heap[i] >= heap[i / 2]` for each `i` in `[2, num]`
+ *
+ * The first element `heap[1]` is always lower or equal to all other elements.
+ *
+ * [[macros]]
+ * Macros
+ * ------
+ ***/
+
+/* For internal usage. */
 #define HEAP_BUBBLE_DOWN_J(heap,num,less,swap)                                         \
   for (;;)                                                                             \
     {                                                                                  \
@@ -22,6 +56,7 @@
       _j = _l;                                                                         \
     }
 
+/* For internal usage. */
 #define HEAP_BUBBLE_UP_J(heap,num,less,swap)                                           \
   while (_j > 1)                                                                       \
     {                                                                                  \
@@ -32,6 +67,9 @@
       _j = _u;                                                                         \
     }
 
+/**
+ * Shuffle the unordered array @heap of @num elements to become a valid heap. The time complexity is linear.
+ **/
 #define HEAP_INIT(type,heap,num,less,swap)                                             \
   do {                                                                                 \
     uns _i = num;                                                                      \
       }                                                                                        \
   } while(0)
 
+/**
+ * Delete the minimum element `heap[1]` in `O(log(n))` time.
+ * The removed value is moved just after the resulting heap (`heap[num + 1]`).
+ **/
 #define HEAP_DELMIN(type,heap,num,less,swap)                                           \
   do {                                                                                 \
     uns _j, _l;                                                                                \
     type x;                                                                            \
     swap(heap,1,num,x);                                                                        \
-    num--;                                                                             \
+    num--;                                                                             \
     _j = 1;                                                                            \
     HEAP_BUBBLE_DOWN_J(heap,num,less,swap);                                            \
   } while(0)
 
+/**
+ * Insert `heap[num]` in `O(log(n))` time. The value of @num must be increased before.
+ **/
 #define HEAP_INSERT(type,heap,num,less,swap)                                           \
   do {                                                                                 \
     uns _j, _u;                                                                                \
     HEAP_BUBBLE_UP_J(heap,num,less,swap);                                              \
   } while(0)
 
+/**
+ * If you need to increase the value of `heap[pos]`, just do it and then call this macro to rebuild the heap.
+ * Only `heap[pos]` can be changed, the rest of the array must form a valid heap.
+ * The time complexity is `O(log(n))`.
+ **/
 #define HEAP_INCREASE(type,heap,num,less,swap,pos)                                     \
   do {                                                                                 \
     uns _j, _l;                                                                                \
     HEAP_BUBBLE_DOWN_J(heap,num,less,swap);                                            \
   } while(0)
 
+/**
+ * If you need to decrease the value of `heap[pos]`, just do it and then call this macro to rebuild the heap.
+ * Only `heap[pos]` can be changed, the rest of the array must form a valid heap.
+ * The time complexity is `O(log(n))`.
+ **/
+#define HEAP_DECREASE(type,heap,num,less,swap,pos)                                     \
+  do {                                                                                 \
+    uns _j, _u;                                                                                \
+    type x;                                                                            \
+    _j = pos;                                                                          \
+    HEAP_BUBBLE_UP_J(heap,num,less,swap);                                              \
+  } while(0)
+
+/**
+ * Delete `heap[pos]` in `O(log(n))` time.
+ **/
 #define HEAP_DELETE(type,heap,num,less,swap,pos)                                       \
   do {                                                                                 \
     uns _j, _l, _u;                                                                    \
       HEAP_BUBBLE_DOWN_J(heap,num,less,swap);                                          \
   } while(0)
 
-/* Default swapping macro */
+/**
+ * Default swapping macro.
+ **/
 #define HEAP_SWAP(heap,a,b,t) (t=heap[a], heap[a]=heap[b], heap[b]=t)