mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-05-22 01:22:51 -06:00
quicksort and binary search for buffers in libgu
This commit is contained in:
@@ -174,6 +174,84 @@ gu_buf_freeze(GuBuf* buf, GuPool* pool)
|
|||||||
return seq;
|
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
|
static void
|
||||||
gu_heap_siftdown(GuBuf *buf, GuOrder *order,
|
gu_heap_siftdown(GuBuf *buf, GuOrder *order,
|
||||||
const void *value, int startpos, int pos)
|
const void *value, int startpos, int pos)
|
||||||
|
|||||||
@@ -130,6 +130,11 @@ gu_buf_flush(GuBuf* buf);
|
|||||||
void
|
void
|
||||||
gu_seq_resize_tail(GuSeq seq, ptrdiff_t change);
|
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
|
// Using a buffer as a heap
|
||||||
void
|
void
|
||||||
|
|||||||
Reference in New Issue
Block a user