quicksort and binary search for buffers in libgu

This commit is contained in:
kr.angelov
2013-08-27 08:06:34 +00:00
parent 584ad7adab
commit a33f2399c2
2 changed files with 83 additions and 0 deletions

View File

@@ -174,6 +174,84 @@ gu_buf_freeze(GuBuf* buf, GuPool* pool)
return seq;
}
static void
gu_quick_sort(GuBuf *buf, GuOrder *order, int left, int right)
{
int l_hold = left;
int r_hold = right;
void* pivot = alloca(buf->elem_size);
memcpy(pivot,
&buf->data[buf->elem_size * left],
buf->elem_size);
while (left < right) {
while ((order->compare(order, &buf->data[buf->elem_size * right], pivot) >= 0) && (left < right))
right--;
if (left != right) {
memcpy(&buf->data[buf->elem_size * left],
&buf->data[buf->elem_size * right],
buf->elem_size);
left++;
}
while ((order->compare(order, &buf->data[buf->elem_size * left], pivot) <= 0) && (left < right))
left++;
if (left != right) {
memcpy(&buf->data[buf->elem_size * right],
&buf->data[buf->elem_size * left],
buf->elem_size);
right--;
}
}
memcpy(&buf->data[buf->elem_size * left],
pivot,
buf->elem_size);
int index = left;
left = l_hold;
right = r_hold;
if (left < index)
gu_quick_sort(buf, order, left, index-1);
if (right > index)
gu_quick_sort(buf, order, index+1, right);
}
void
gu_buf_sort(GuBuf *buf, GuOrder *order)
{
gu_quick_sort(buf, order, 0, gu_buf_length(buf) - 1);
}
bool
gu_buf_binsearch(GuBuf *buf, GuOrder *order, void *value)
{
size_t i = 0;
size_t j = gu_buf_length(buf)-1;
while (i <= j) {
size_t k = (i+j) / 2;
int cmp = order->compare(order, value, &buf->data[buf->elem_size * k]);
if (cmp < 0) {
j = k-1;
} else if (cmp > 0) {
i = k+1;
} else {
memcpy(value,
&buf->data[buf->elem_size * k],
buf->elem_size);
return true;
}
}
return false;
}
static void
gu_heap_siftdown(GuBuf *buf, GuOrder *order,
const void *value, int startpos, int pos)

View File

@@ -130,6 +130,11 @@ gu_buf_flush(GuBuf* buf);
void
gu_seq_resize_tail(GuSeq seq, ptrdiff_t change);
void
gu_buf_sort(GuBuf *buf, GuOrder *order);
bool
gu_buf_binsearch(GuBuf *buf, GuOrder *order, void *value);
// Using a buffer as a heap
void