aboutsummaryrefslogtreecommitdiff
path: root/src/algo.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/algo.c')
-rw-r--r--src/algo.c230
1 files changed, 215 insertions, 15 deletions
diff --git a/src/algo.c b/src/algo.c
index 7f3287d..2d2d0ac 100644
--- a/src/algo.c
+++ b/src/algo.c
@@ -1,34 +1,72 @@
#include <bh/algo.h>
#include <string.h>
-#include <stdio.h>
-void bh_swap(void *lhs,
- void *rhs,
+/**
+ * \defgroup algo Algorithms
+ *
+ * Common algorithms (search, swap, heap, etc)
+ * \{
+ */
+
+/**
+ * Swaps \a size bytes between the object pointed to by \a src and object
+ * pointed to by \a dest.
+ *
+ * If the objects overlap, the behavior is undefined.
+ *
+ * If either \a src or \a dest is an invalid or null pointer, the behavior is
+ * undefined.
+ *
+ * \param dest Pointer to the memory location to swap to
+ * \param src Pointer to the memory location to swap from
+ * \param size Number of bytes to swap
+ */
+void bh_swap(void *dest,
+ void *src,
size_t size)
{
int tmp;
- /* Swap values in int sized chunks */
+ /* Swap bytes in int-sized chunks */
while (size >= sizeof(tmp))
{
- memmove(&tmp, lhs, sizeof(tmp));
- memmove(lhs, rhs, sizeof(tmp));
- memmove(rhs, &tmp, sizeof(tmp));
+ memmove(&tmp, dest, sizeof(tmp));
+ memmove(dest, src, sizeof(tmp));
+ memmove(src, &tmp, sizeof(tmp));
- lhs = (char *)lhs + sizeof(tmp);
- rhs = (char *)rhs + sizeof(tmp);
+ dest = (char *)dest + sizeof(tmp);
+ src = (char *)src + sizeof(tmp);
size -= sizeof(tmp);
}
- /* Swap the rest */
+ /* Swap the remaining size */
if (size)
{
- memmove(&tmp, lhs, size);
- memmove(lhs, rhs, size);
- memmove(rhs, &tmp, size);
+ memmove(&tmp, dest, size);
+ memmove(dest, src, size);
+ memmove(src, &tmp, size);
}
}
+/**
+ * Partitions the \a array of \a size elements of \a element bytes, relative to
+ * the specified \a pivot element. Function pointed by \a equal is used for
+ * comparison.
+ *
+ * If the \a pivot element is part of the partitioned \a array, function will
+ * behaive the same way, as if \a pivot element wasn't part of the array.
+ *
+ * If \a equal indicates two elements as equivalent, their order in the
+ * resulting partitioned array is unspecified.
+ *
+ * \param pivot Pointer to the pivot element
+ * \param array Pointer to the array to partition
+ * \param size Number of elements in the array
+ * \param element Size of each element in the array in bytes
+ * \param equal Comparision function
+ *
+ * \return Pointer to the first element of the second partition.
+ */
void *bh_partition(void *pivot,
void *array,
size_t size,
@@ -74,6 +112,17 @@ void *bh_partition(void *pivot,
return j + element;
}
+/**
+ * Sorts the \a array of \a size elements of \a element bytes. Function pointed
+ * by \a equal is used for comparision.
+ *
+ * This sorting does not make any gurantees about time or space complexity.
+ *
+ * \param array Pointer to the array to sort
+ * \param size Number of elements in the array
+ * \param element Size of each element in the array in bytes
+ * \param equal Comparision function
+ */
void bh_sort(void *array,
size_t size,
size_t element,
@@ -83,6 +132,23 @@ void bh_sort(void *array,
bh_sort_intro(array, size, element, equal);
}
+
+/**
+ * Sorts the \a array of \a size elements of \a element bytes with insertion
+ * sort. Function pointed by \a equal is used for comparision.
+ *
+ * This sorting has following time complexity:
+ * - best case O(n)
+ * - average case O(n^2)
+ * - worst case O(n^2)
+ *
+ * This sorting has O(1) space complexity.
+ *
+ * \param array Pointer to the array to sort
+ * \param size Number of elements in the array
+ * \param element Size of each element in the array in bytes
+ * \param equal Comparision function
+ */
void bh_sort_insert(void *array,
size_t size,
size_t element,
@@ -109,6 +175,20 @@ void bh_sort_insert(void *array,
}
+/**
+ * Sorts the \a array of \a size elements of \a element bytes with shell sort.
+ * Function pointed by \a equal is used for comparision.
+ *
+ * This sorting has the O(n log n) best cast time complexity. Average and worst
+ * cases are implementation dependant.
+ *
+ * This sorting has O(1) space complexity.
+ *
+ * \param array Pointer to the array to sort
+ * \param size Number of elements in the array
+ * \param element Size of each element in the array in bytes
+ * \param equal Comparision function
+ */
void bh_sort_shell(void *array,
size_t size,
size_t element,
@@ -118,7 +198,7 @@ void bh_sort_shell(void *array,
const size_t *gap;
size_t i, j;
- /* Shell sort with A102549 sequence*/
+ /* Shell sort with A102549 sequence */
for (gap = gaps; gap < gaps + sizeof(gaps) / sizeof(*gaps); gap++)
{
for (i = *gap; i < size; i++)
@@ -201,6 +281,22 @@ static void bh_sort_intro_r(void *array,
}
}
+/**
+ * Sorts the \a array of \a size elements of \a element bytes with insertion
+ * sort. Function pointed by \a equal is used for comparision.
+ *
+ * This sorting has following time complexity:
+ * - best case O(n log n)
+ * - average case O(n log n)
+ * - worst case O(n log n)
+ *
+ * This sorting has O(log n) space complexity.
+ *
+ * \param array Pointer to the array to sort
+ * \param size Number of elements in the array
+ * \param element Size of each element in the array in bytes
+ * \param equal Comparision function
+ */
void bh_sort_intro(void *array,
size_t size,
size_t element,
@@ -221,6 +317,22 @@ void bh_sort_intro(void *array,
bh_sort_intro_r(array, size, element, equal, depth);
}
+/**
+ * Sorts the \a array of \a size elements of \a element bytes with insertion
+ * sort. Function pointed by \a equal is used for comparision.
+ *
+ * This sorting has following time complexity:
+ * - best case O(n)
+ * - average case O(n log n)
+ * - worst case O(n log n)
+ *
+ * This sorting has O(1) space complexity.
+ *
+ * \param array Pointer to the array to sort
+ * \param size Number of elements in the array
+ * \param element Size of each element in the array in bytes
+ * \param equal Comparision function
+ */
void bh_sort_heap(void *array,
size_t size,
size_t element,
@@ -232,7 +344,15 @@ void bh_sort_heap(void *array,
bh_heap_remove(array, size--, element, equal);
}
-
+/**
+ * Heapifes the \a array of \a size elements of \a element bytes. Function
+ * pointed by \a equal is used for comparision.
+ *
+ * \param array Pointer to the array to heapify
+ * \param size Number of elements in the array
+ * \param element Size of each element in the array in bytes
+ * \param equal Comparision function
+ */
void bh_heap_make(void *array,
size_t size,
size_t element,
@@ -279,6 +399,15 @@ void bh_heap_make(void *array,
}
}
+/**
+ * Removes top element from heapified \a array of \a size elements of \a
+ * elements bytes. Function pointed by \a equal is used for comparasion.
+ *
+ * \param array Pointer to the array to remove element from
+ * \param size Number of elements in the array
+ * \param element Size of each element in the array in bytes
+ * \param equal Comparasion function
+ */
void bh_heap_remove(void *array,
size_t size,
size_t element,
@@ -323,6 +452,16 @@ void bh_heap_remove(void *array,
}
}
+/**
+ * Inserts new element into heapified \a array of \a size elements of \a
+ * elements bytes. Function pointed by \a equal is used for comparasion.
+ *
+ * \param value Pointer to the value to be inserted
+ * \param array Pointer to the array to remove element from
+ * \param size Number of elements in the array
+ * \param element Size of each element in the array in bytes
+ * \param equal Comparasion function
+ */
void bh_heap_insert(void *value,
void *array,
size_t size,
@@ -358,3 +497,64 @@ void bh_heap_insert(void *value,
break;
}
}
+
+/**
+ * Replaces top element of the heapified \a array of \a size elements of \a
+ * elements bytes. Function pointed by \a equal is used for comparasion.
+ *
+ * This function is equal to two consecutive operations of remove and insert.
+ *
+ * \param value Pointer to the value to be inserted
+ * \param array Pointer to the array to remove element from
+ * \param size Number of elements in the array
+ * \param element Size of each element in the array in bytes
+ * \param equal Comparasion function
+ */
+void bh_heap_replace(void *value,
+ void *array,
+ size_t size,
+ size_t element,
+ bh_equal_cb_t equal)
+{
+ char *start, *end, *current, *left, *right;
+
+ if (size <= 1)
+ return;
+
+ /* Calculate start, end and children pointers */
+ start = (char *)array;
+ end = start + size * element;
+ current = start;
+ left = start + (current - start) * 2 + element;
+ right = left + element;
+
+ /* Copy supplied element to the first (top) position */
+ memmove(current, value, element);
+
+ /* Iterate until we reach the end */
+ while (left < end)
+ {
+ char *biggest;
+
+ /* Determine biggest child */
+ biggest = left;
+ if (right < end && equal(left, right) < 0)
+ biggest = right;
+
+ /* Compare biggest child with current */
+ if (equal(current, biggest) < 0)
+ {
+ /* Swap content and recalculate children pointers */
+ bh_swap(current, biggest, element);
+ current = biggest;
+ left = start + (current - start) * 2 + element;
+ right = left + element;
+ }
+ else
+ break;
+ }
+}
+
+/**
+ * \}
+ */ \ No newline at end of file