added qse_arr_updateheap(), qse_arr_deleteheap()
This commit is contained in:
parent
7f24950536
commit
6b9fd818f8
@ -92,6 +92,11 @@ typedef void (*qse_arr_freeer_t) (
|
|||||||
* the arry needs to compare data. A linear dynamic array is created with a
|
* the arry needs to compare data. A linear dynamic array is created with a
|
||||||
* default comparator that performs bitwise comparison.
|
* default comparator that performs bitwise comparison.
|
||||||
*
|
*
|
||||||
|
* The default comparator compares data in a memcmp-like fashion.
|
||||||
|
* It is not suitable when you want to implement a heap of numbers
|
||||||
|
* greater than a byte size. You must implement a comparator that
|
||||||
|
* takes the whole element and performs comparison in such a case.
|
||||||
|
*
|
||||||
* The comparator should return 0 if the data are the same, a negative
|
* The comparator should return 0 if the data are the same, a negative
|
||||||
* integer if the first data is less than the second data, a positive
|
* integer if the first data is less than the second data, a positive
|
||||||
* integer otherwise.
|
* integer otherwise.
|
||||||
@ -259,7 +264,8 @@ QSE_EXPORT qse_arr_comper_t qse_arr_getcomper (
|
|||||||
/**
|
/**
|
||||||
* The qse_arr_setcomper() function specifies how to compare two elements
|
* The qse_arr_setcomper() function specifies how to compare two elements
|
||||||
* for equality test. The comparator @a comper must return 0 if two elements
|
* for equality test. The comparator @a comper must return 0 if two elements
|
||||||
* compared are equal, or a non-zero number otherwise.
|
* compared are equal, 1 if the first element is greater than the
|
||||||
|
* second, -1 if the second element is greater than the first.
|
||||||
*/
|
*/
|
||||||
QSE_EXPORT void qse_arr_setcomper (
|
QSE_EXPORT void qse_arr_setcomper (
|
||||||
qse_arr_t* arr /**< arr */,
|
qse_arr_t* arr /**< arr */,
|
||||||
@ -428,6 +434,18 @@ QSE_EXPORT void qse_arr_popheap (
|
|||||||
qse_arr_t* arr
|
qse_arr_t* arr
|
||||||
);
|
);
|
||||||
|
|
||||||
|
QSE_EXPORT void qse_arr_deleteheap (
|
||||||
|
qse_arr_t* arr,
|
||||||
|
qse_size_t index
|
||||||
|
);
|
||||||
|
|
||||||
|
QSE_EXPORT qse_size_t qse_arr_updateheap (
|
||||||
|
qse_arr_t* arr,
|
||||||
|
qse_size_t index,
|
||||||
|
void* dptr,
|
||||||
|
qse_size_t dlen
|
||||||
|
);
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -43,6 +43,8 @@
|
|||||||
#define DPTR(slot) ((slot)->val.ptr)
|
#define DPTR(slot) ((slot)->val.ptr)
|
||||||
#define DLEN(slot) ((slot)->val.len)
|
#define DLEN(slot) ((slot)->val.len)
|
||||||
|
|
||||||
|
/* the default comparator is not proper for number comparision.
|
||||||
|
* the first different byte decides whice side is greater */
|
||||||
static int default_comparator (arr_t* arr,
|
static int default_comparator (arr_t* arr,
|
||||||
const void* dptr1, size_t dlen1,
|
const void* dptr1, size_t dlen1,
|
||||||
const void* dptr2, size_t dlen2)
|
const void* dptr2, size_t dlen2)
|
||||||
@ -52,8 +54,11 @@ static int default_comparator (arr_t* arr,
|
|||||||
return 1;
|
return 1;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
size_t min = (dlen1 < dlen2)? dlen1: dlen2;
|
int n;
|
||||||
int n = QSE_MEMCMP (dptr1, dptr2, TOB(arr,min));
|
size_t min;
|
||||||
|
|
||||||
|
min = (dlen1 < dlen2)? dlen1: dlen2;
|
||||||
|
n = QSE_MEMCMP (dptr1, dptr2, TOB(arr,min));
|
||||||
if (n == 0 && dlen1 != dlen2)
|
if (n == 0 && dlen1 != dlen2)
|
||||||
{
|
{
|
||||||
n = (dlen1 > dlen2)? 1: -1;
|
n = (dlen1 > dlen2)? 1: -1;
|
||||||
@ -378,8 +383,7 @@ size_t qse_arr_insert (arr_t* arr, size_t pos, void* dptr, size_t dlen)
|
|||||||
|
|
||||||
if (capa <= mincapa)
|
if (capa <= mincapa)
|
||||||
{
|
{
|
||||||
if (arr->freeer)
|
if (arr->freeer) arr->freeer (arr, DPTR(slot), DLEN(slot));
|
||||||
arr->freeer (arr, DPTR(slot), DLEN(slot));
|
|
||||||
QSE_MMGR_FREE (arr->mmgr, slot);
|
QSE_MMGR_FREE (arr->mmgr, slot);
|
||||||
return QSE_ARR_NIL;
|
return QSE_ARR_NIL;
|
||||||
}
|
}
|
||||||
@ -392,8 +396,7 @@ size_t qse_arr_insert (arr_t* arr, size_t pos, void* dptr, size_t dlen)
|
|||||||
if (pos >= arr->capa || arr->size >= arr->capa)
|
if (pos >= arr->capa || arr->size >= arr->capa)
|
||||||
{
|
{
|
||||||
/* the buffer is not still enough after resizing */
|
/* the buffer is not still enough after resizing */
|
||||||
if (arr->freeer)
|
if (arr->freeer) arr->freeer (arr, DPTR(slot), DLEN(slot));
|
||||||
arr->freeer (arr, DPTR(slot), DLEN(slot));
|
|
||||||
QSE_MMGR_FREE (arr->mmgr, slot);
|
QSE_MMGR_FREE (arr->mmgr, slot);
|
||||||
return QSE_ARR_NIL;
|
return QSE_ARR_NIL;
|
||||||
}
|
}
|
||||||
@ -439,8 +442,7 @@ size_t qse_arr_update (arr_t* arr, size_t pos, void* dptr, size_t dlen)
|
|||||||
slot_t* slot = alloc_slot (arr, dptr, dlen);
|
slot_t* slot = alloc_slot (arr, dptr, dlen);
|
||||||
if (slot == QSE_NULL) return QSE_ARR_NIL;
|
if (slot == QSE_NULL) return QSE_ARR_NIL;
|
||||||
|
|
||||||
if (arr->freeer != QSE_NULL)
|
if (arr->freeer) arr->freeer (arr, DPTR(c), DLEN(c));
|
||||||
arr->freeer (arr, DPTR(c), DLEN(c));
|
|
||||||
QSE_MMGR_FREE (arr->mmgr, c);
|
QSE_MMGR_FREE (arr->mmgr, c);
|
||||||
|
|
||||||
arr->slot[pos] = slot;
|
arr->slot[pos] = slot;
|
||||||
@ -465,8 +467,7 @@ size_t qse_arr_delete (arr_t* arr, size_t index, size_t count)
|
|||||||
|
|
||||||
if (c != QSE_NULL)
|
if (c != QSE_NULL)
|
||||||
{
|
{
|
||||||
if (arr->freeer != QSE_NULL)
|
if (arr->freeer) arr->freeer (arr, DPTR(c), DLEN(c));
|
||||||
arr->freeer (arr, DPTR(c), DLEN(c));
|
|
||||||
QSE_MMGR_FREE (arr->mmgr, c);
|
QSE_MMGR_FREE (arr->mmgr, c);
|
||||||
|
|
||||||
arr->slot[i] = QSE_NULL;
|
arr->slot[i] = QSE_NULL;
|
||||||
@ -498,8 +499,7 @@ size_t qse_arr_uplete (arr_t* arr, size_t index, size_t count)
|
|||||||
|
|
||||||
if (c != QSE_NULL)
|
if (c != QSE_NULL)
|
||||||
{
|
{
|
||||||
if (arr->freeer != QSE_NULL)
|
if (arr->freeer) arr->freeer (arr, DPTR(c), DLEN(c));
|
||||||
arr->freeer (arr, DPTR(c), DLEN(c));
|
|
||||||
QSE_MMGR_FREE (arr->mmgr, c);
|
QSE_MMGR_FREE (arr->mmgr, c);
|
||||||
|
|
||||||
arr->slot[i] = QSE_NULL;
|
arr->slot[i] = QSE_NULL;
|
||||||
@ -608,93 +608,163 @@ void qse_arr_popstack (arr_t* arr)
|
|||||||
#define HEAP_LEFT(x) ((x)*2 + 1)
|
#define HEAP_LEFT(x) ((x)*2 + 1)
|
||||||
#define HEAP_RIGHT(x) ((x)*2 + 2)
|
#define HEAP_RIGHT(x) ((x)*2 + 2)
|
||||||
|
|
||||||
size_t qse_arr_pushheap (arr_t* arr, void* dptr, size_t dlen)
|
size_t sift_up (arr_t* arr, size_t index)
|
||||||
{
|
{
|
||||||
size_t cur, par;
|
size_t parent;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
/* add a value to the bottom */
|
if (index > 0)
|
||||||
cur = arr->size;
|
{
|
||||||
if (qse_arr_insert (arr, cur, dptr, dlen) == QSE_ARR_NIL)
|
parent = HEAP_PARENT(index);
|
||||||
return QSE_ARR_NIL;
|
n = arr->comper (arr,
|
||||||
|
DPTR(arr->slot[index]), DLEN(arr->slot[index]),
|
||||||
while (cur != 0)
|
DPTR(arr->slot[parent]), DLEN(arr->slot[parent]));
|
||||||
|
if (n > 0)
|
||||||
{
|
{
|
||||||
slot_t* tmp;
|
slot_t* tmp;
|
||||||
|
|
||||||
/* compare with the parent */
|
tmp = arr->slot[index];
|
||||||
par = HEAP_PARENT(cur);
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
arr->slot[index] = arr->slot[parent];
|
||||||
|
|
||||||
|
index = parent;
|
||||||
|
parent = HEAP_PARENT(parent);
|
||||||
|
|
||||||
|
if (index <= 0) break;
|
||||||
|
|
||||||
n = arr->comper (arr,
|
n = arr->comper (arr,
|
||||||
DPTR(arr->slot[cur]), DLEN(arr->slot[cur]),
|
DPTR(tmp), DLEN(tmp),
|
||||||
DPTR(arr->slot[par]), DLEN(arr->slot[par]));
|
DPTR(arr->slot[parent]), DLEN(arr->slot[parent]));
|
||||||
if (n <= 0) break; /* ok */
|
if (n <= 0) break;
|
||||||
|
|
||||||
/* swap the current with the parent */
|
|
||||||
tmp = arr->slot[cur];
|
|
||||||
arr->slot[cur] = arr->slot[par];
|
|
||||||
arr->slot[par] = tmp;
|
|
||||||
|
|
||||||
cur = par;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
arr->slot[index] = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t sift_down (arr_t* arr, size_t index)
|
||||||
|
{
|
||||||
|
size_t base;
|
||||||
|
|
||||||
|
base = arr->size / 2;
|
||||||
|
|
||||||
|
if (index < base) /* at least 1 child is under the 'index' position */
|
||||||
|
{
|
||||||
|
slot_t* tmp;
|
||||||
|
|
||||||
|
tmp = arr->slot[index];
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
qse_size_t left, right, child;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
left= HEAP_LEFT(index);
|
||||||
|
right = HEAP_RIGHT(index);
|
||||||
|
|
||||||
|
if (right < arr->size)
|
||||||
|
{
|
||||||
|
n = arr->comper (arr,
|
||||||
|
DPTR(arr->slot[right]), DLEN(arr->slot[right]),
|
||||||
|
DPTR(arr->slot[left]), DLEN(arr->slot[left]));
|
||||||
|
child = (n > 0)? right: left;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
child = left;
|
||||||
|
}
|
||||||
|
|
||||||
|
n = arr->comper (arr,
|
||||||
|
DPTR(tmp), DLEN(tmp),
|
||||||
|
DPTR(arr->slot[child]), DLEN(arr->slot[child]));
|
||||||
|
if (n > 0) break;
|
||||||
|
|
||||||
|
arr->slot[index] = arr->slot[child];
|
||||||
|
index = child;
|
||||||
|
}
|
||||||
|
while (index < base);
|
||||||
|
|
||||||
|
arr->slot[index] = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t qse_arr_pushheap (arr_t* arr, void* dptr, size_t dlen)
|
||||||
|
{
|
||||||
|
size_t index;
|
||||||
|
|
||||||
|
/* add a value at the back of the array */
|
||||||
|
index = arr->size;
|
||||||
|
if (qse_arr_insert (arr, index, dptr, dlen) == QSE_ARR_NIL) return QSE_ARR_NIL;
|
||||||
|
|
||||||
|
QSE_ASSERT (arr->size == index + 1);
|
||||||
|
|
||||||
|
/* move the item upto the top if it's greater than the parent items */
|
||||||
|
sift_up (arr, index);
|
||||||
return arr->size;
|
return arr->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void qse_arr_popheap (arr_t* arr)
|
void qse_arr_popheap (arr_t* arr)
|
||||||
{
|
{
|
||||||
size_t cur, child;
|
QSE_ASSERT (arr->size > 0);
|
||||||
|
qse_arr_deleteheap (arr, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void qse_arr_deleteheap (arr_t* arr, size_t index)
|
||||||
|
{
|
||||||
slot_t* tmp;
|
slot_t* tmp;
|
||||||
|
|
||||||
QSE_ASSERT (arr->size > 0);
|
QSE_ASSERT (arr->size > 0);
|
||||||
|
QSE_ASSERT (index < arr->size);
|
||||||
|
|
||||||
/* destroy the top */
|
/* remember the item to destroy */
|
||||||
tmp = arr->slot[0];
|
tmp = arr->slot[index];
|
||||||
|
|
||||||
|
arr->size = arr->size - 1;
|
||||||
|
if (arr->size > 0 && index != arr->size)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
|
||||||
|
/* move the last item to the deleting position */
|
||||||
|
arr->slot[index] = arr->slot[arr->size];
|
||||||
|
|
||||||
|
/* move it up if the last item is greater than the item to be deleted,
|
||||||
|
* move it down otherwise. */
|
||||||
|
n = arr->comper (arr,
|
||||||
|
DPTR(arr->slot[index]), DLEN(arr->slot[index]),
|
||||||
|
DPTR(tmp), DLEN(tmp));
|
||||||
|
if (n > 0) sift_up (arr, index);
|
||||||
|
else if (n < 0) sift_down (arr, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* destroy the actual item */
|
||||||
if (arr->freeer) arr->freeer (arr, DPTR(tmp), DLEN(tmp));
|
if (arr->freeer) arr->freeer (arr, DPTR(tmp), DLEN(tmp));
|
||||||
QSE_MMGR_FREE (arr->mmgr, tmp);
|
QSE_MMGR_FREE (arr->mmgr, tmp);
|
||||||
|
|
||||||
/* move the last item to the top position also shrink the size */
|
/* empty the last slot */
|
||||||
arr->slot[0] = arr->slot[--arr->size];
|
arr->slot[arr->size] = QSE_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (arr->size <= 1) return; /* only 1 element. nothing further to do */
|
size_t qse_arr_updateheap (qse_arr_t* arr, qse_size_t index, void* dptr, qse_size_t dlen)
|
||||||
|
{
|
||||||
for (cur = 0; cur < arr->size; cur = child)
|
slot_t* tmp;
|
||||||
{
|
|
||||||
size_t left, right;
|
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
left = HEAP_LEFT(cur);
|
tmp = arr->slot[index];
|
||||||
right = HEAP_RIGHT(cur);
|
QSE_ASSERT (tmp != QSE_NULL);
|
||||||
|
|
||||||
if (left >= arr->size)
|
n = arr->comper (arr, dptr, dlen, DPTR(tmp), DLEN(tmp));
|
||||||
|
if (n)
|
||||||
{
|
{
|
||||||
/* the left child does not exist.
|
if (qse_arr_update (arr, index, dptr, dlen) == QSE_ARR_NIL) return QSE_ARR_NIL;
|
||||||
* reached the bottom. abort exchange */
|
if (n > 0) sift_up (arr, index);
|
||||||
break;
|
else sift_down (arr, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (right >= arr->size)
|
return index;
|
||||||
{
|
|
||||||
/* the right child does not exist. only the left */
|
|
||||||
child = left;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* get the larger child of the two */
|
|
||||||
n = arr->comper (arr,
|
|
||||||
DPTR(arr->slot[left]), DLEN(arr->slot[left]),
|
|
||||||
DPTR(arr->slot[right]), DLEN(arr->slot[right]));
|
|
||||||
child = (n > 0)? left: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* compare the current one with the child */
|
|
||||||
n = arr->comper (arr,
|
|
||||||
DPTR(arr->slot[cur]), DLEN(arr->slot[cur]),
|
|
||||||
DPTR(arr->slot[child]), DLEN(arr->slot[child]));
|
|
||||||
if (n > 0) break; /* current one is larger. stop exchange */
|
|
||||||
|
|
||||||
/* swap the current with the child */
|
|
||||||
tmp = arr->slot[cur];
|
|
||||||
arr->slot[cur] = arr->slot[child];
|
|
||||||
arr->slot[child] = tmp;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -137,7 +137,7 @@ static qse_tmr_index_t sift_down (qse_tmr_t* tmr, qse_tmr_index_t index, int not
|
|||||||
{
|
{
|
||||||
qse_size_t base = tmr->size / 2;
|
qse_size_t base = tmr->size / 2;
|
||||||
|
|
||||||
if (index < base) /* at least 1 child is under the 'index' positmrn */
|
if (index < base) /* at least 1 child is under the 'index' position */
|
||||||
{
|
{
|
||||||
qse_tmr_event_t item;
|
qse_tmr_event_t item;
|
||||||
qse_size_t old_index;
|
qse_size_t old_index;
|
||||||
@ -149,7 +149,7 @@ static qse_tmr_index_t sift_down (qse_tmr_t* tmr, qse_tmr_index_t index, int not
|
|||||||
{
|
{
|
||||||
qse_size_t left, right, younger;
|
qse_size_t left, right, younger;
|
||||||
|
|
||||||
left= HEAP_LEFT(index);
|
left = HEAP_LEFT(index);
|
||||||
right = HEAP_RIGHT(index);
|
right = HEAP_RIGHT(index);
|
||||||
|
|
||||||
if (right < tmr->size && YOUNGER_THAN(&tmr->event[right], &tmr->event[left]))
|
if (right < tmr->size && YOUNGER_THAN(&tmr->event[right], &tmr->event[left]))
|
||||||
|
@ -372,6 +372,14 @@ static int test4 ()
|
|||||||
|
|
||||||
qse_arr_comper_t default_comparator;
|
qse_arr_comper_t default_comparator;
|
||||||
|
|
||||||
|
static int integer_comparator (qse_arr_t* arr,
|
||||||
|
const void* dptr1, size_t dlen1,
|
||||||
|
const void* dptr2, size_t dlen2)
|
||||||
|
{
|
||||||
|
return (*(int*)dptr1 > *(int*)dptr2)? 1:
|
||||||
|
(*(int*)dptr1 < *(int*)dptr2)? -1: 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int inverse_comparator (qse_arr_t* arr,
|
static int inverse_comparator (qse_arr_t* arr,
|
||||||
const void* dptr1, size_t dlen1,
|
const void* dptr1, size_t dlen1,
|
||||||
const void* dptr2, size_t dlen2)
|
const void* dptr2, size_t dlen2)
|
||||||
@ -382,7 +390,7 @@ static int inverse_comparator (qse_arr_t* arr,
|
|||||||
static int test5 ()
|
static int test5 ()
|
||||||
{
|
{
|
||||||
qse_arr_t* s1;
|
qse_arr_t* s1;
|
||||||
int i, j;
|
int i, j, oldv, newv;
|
||||||
|
|
||||||
s1 = qse_arr_open (QSE_MMGR_GETDFL(), 0, 3);
|
s1 = qse_arr_open (QSE_MMGR_GETDFL(), 0, 3);
|
||||||
if (s1 == QSE_NULL)
|
if (s1 == QSE_NULL)
|
||||||
@ -393,55 +401,74 @@ static int test5 ()
|
|||||||
|
|
||||||
qse_arr_setcopier (s1, QSE_ARR_COPIER_INLINE);
|
qse_arr_setcopier (s1, QSE_ARR_COPIER_INLINE);
|
||||||
qse_arr_setscale (s1, QSE_SIZEOF(i));
|
qse_arr_setscale (s1, QSE_SIZEOF(i));
|
||||||
|
qse_arr_setcomper (s1, integer_comparator);
|
||||||
|
|
||||||
/* inverse the comparator to implement min-heap */
|
/* inverse the comparator to implement min-heap */
|
||||||
default_comparator = qse_arr_getcomper (s1);
|
default_comparator = qse_arr_getcomper (s1);
|
||||||
qse_arr_setcomper (s1, inverse_comparator);
|
qse_arr_setcomper (s1, inverse_comparator);
|
||||||
|
|
||||||
for (i = 0; i < 25; i++)
|
for (i = 0; i < 2500; i++)
|
||||||
{
|
{
|
||||||
j = rand () % 100;
|
j = rand () % 1000;
|
||||||
qse_arr_pushheap (s1, &j, 1);
|
qse_arr_pushheap (s1, &j, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
qse_printf (QSE_T("arr size => %lu\n"), QSE_ARR_SIZE(s1));
|
qse_printf (QSE_T("arr size => %lu\n"), QSE_ARR_SIZE(s1));
|
||||||
qse_arr_walk (s1, walker3, QSE_NULL);
|
qse_arr_walk (s1, walker3, QSE_NULL);
|
||||||
|
|
||||||
|
oldv = 0;
|
||||||
while (QSE_ARR_SIZE(s1) > 10 )
|
while (QSE_ARR_SIZE(s1) > 10 )
|
||||||
{
|
{
|
||||||
qse_printf (QSE_T("top => %d\n"), *(int*)QSE_ARR_DPTR(s1,0));
|
newv = *(int*)QSE_ARR_DPTR(s1,0);
|
||||||
|
qse_printf (QSE_T("top => %d prevtop => %d\n"), newv, oldv);
|
||||||
|
QSE_ASSERT (newv >= oldv);
|
||||||
qse_arr_popheap (s1);
|
qse_arr_popheap (s1);
|
||||||
|
oldv = newv;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < 25; i++)
|
for (i = 0; i < 2500; i++)
|
||||||
{
|
{
|
||||||
j = rand () % 100;
|
j = rand () % 1000;
|
||||||
qse_arr_pushheap (s1, &j, 1);
|
qse_arr_pushheap (s1, &j, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
qse_printf (QSE_T("arr size => %lu\n"), QSE_ARR_SIZE(s1));
|
qse_printf (QSE_T("arr size => %lu\n"), QSE_ARR_SIZE(s1));
|
||||||
qse_arr_walk (s1, walker3, QSE_NULL);
|
qse_arr_walk (s1, walker3, QSE_NULL);
|
||||||
|
|
||||||
while (QSE_ARR_SIZE(s1))
|
oldv = 0;
|
||||||
|
while (QSE_ARR_SIZE(s1) > 0)
|
||||||
{
|
{
|
||||||
qse_printf (QSE_T("top => %d\n"), *(int*)QSE_ARR_DPTR(s1,0));
|
newv = *(int*)QSE_ARR_DPTR(s1,0);
|
||||||
|
qse_printf (QSE_T("top => %d prevtop => %d\n"), newv, oldv);
|
||||||
|
QSE_ASSERT (newv >= oldv);
|
||||||
qse_arr_popheap (s1);
|
qse_arr_popheap (s1);
|
||||||
|
oldv = newv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* back to max-heap */
|
||||||
qse_arr_setcomper (s1, default_comparator);
|
qse_arr_setcomper (s1, default_comparator);
|
||||||
for (i = 0; i < 25; i++)
|
for (i = 0; i < 2500; i++)
|
||||||
{
|
{
|
||||||
j = rand () % 100;
|
j = rand () % 1000;
|
||||||
qse_arr_pushheap (s1, &j, 1);
|
qse_arr_pushheap (s1, &j, 1);
|
||||||
}
|
}
|
||||||
|
j = 88888888;
|
||||||
|
qse_arr_updateheap (s1, QSE_ARR_SIZE(s1) / 2, &j, 1);
|
||||||
|
j = -123;
|
||||||
|
qse_arr_updateheap (s1, QSE_ARR_SIZE(s1) / 2, &j, 1);
|
||||||
|
|
||||||
qse_printf (QSE_T("arr size => %lu\n"), QSE_ARR_SIZE(s1));
|
qse_printf (QSE_T("arr size => %lu\n"), QSE_ARR_SIZE(s1));
|
||||||
qse_arr_walk (s1, walker3, QSE_NULL);
|
qse_arr_walk (s1, walker3, QSE_NULL);
|
||||||
|
|
||||||
while (QSE_ARR_SIZE(s1))
|
|
||||||
|
oldv = 99999999;
|
||||||
|
while (QSE_ARR_SIZE(s1) > 0)
|
||||||
{
|
{
|
||||||
qse_printf (QSE_T("top => %d\n"), *(int*)QSE_ARR_DPTR(s1,0));
|
newv = *(int*)QSE_ARR_DPTR(s1,0);
|
||||||
|
qse_printf (QSE_T("top => %d prevtop => %d\n"), newv, oldv);
|
||||||
|
QSE_ASSERT (newv <= oldv);
|
||||||
qse_arr_popheap (s1);
|
qse_arr_popheap (s1);
|
||||||
|
oldv = newv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <qse/cmn/BinaryHeap.hpp>
|
#include <qse/cmn/BinaryHeap.hpp>
|
||||||
#include <qse/cmn/String.hpp>
|
#include <qse/cmn/String.hpp>
|
||||||
#include <qse/cmn/alg.h>
|
#include <qse/cmn/alg.h>
|
||||||
#include <qse/cmn/time.h>
|
#include <qse/cmn/time.h>
|
||||||
|
|
||||||
|
|
||||||
|
//#define MAX_HEAP
|
||||||
|
|
||||||
class Julia
|
class Julia
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -60,7 +63,11 @@ public:
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(MAX_HEAP)
|
||||||
bool operator> (const Julia& q) const { return *this->x > *q.x; }
|
bool operator> (const Julia& q) const { return *this->x > *q.x; }
|
||||||
|
#else
|
||||||
|
bool operator> (const Julia& q) const { return *this->x < *q.x; }
|
||||||
|
#endif
|
||||||
int* x;
|
int* x;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -71,20 +78,36 @@ int main ()
|
|||||||
JuliaHeap jh;
|
JuliaHeap jh;
|
||||||
qse_uint32_t x;
|
qse_uint32_t x;
|
||||||
qse_ntime_t nt;
|
qse_ntime_t nt;
|
||||||
|
int oldval, newval;
|
||||||
|
|
||||||
qse_gettime (&nt);
|
qse_gettime (&nt);
|
||||||
|
|
||||||
x = nt.sec + nt.nsec;
|
x = nt.sec + nt.nsec;
|
||||||
|
|
||||||
for (int i = 0; i < 100; i++)
|
for (int i = 0; i < 2500; i++)
|
||||||
{
|
{
|
||||||
x = qse_rand31(x);
|
//x = qse_rand31(x);
|
||||||
jh.insert (Julia((int)x % 100));
|
x = rand();
|
||||||
|
jh.insert (Julia((int)x % 1000));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(MAX_HEAP)
|
||||||
|
oldval = 9999999;
|
||||||
|
#else
|
||||||
|
oldval = 0;
|
||||||
|
#endif
|
||||||
while (!jh.isEmpty())
|
while (!jh.isEmpty())
|
||||||
{
|
{
|
||||||
printf ("%d\n", *jh.getValueAt(0).x);
|
newval = *jh.getValueAt(0).x;
|
||||||
|
printf ("%d oldval => %d\n", newval, oldval);
|
||||||
|
#if defined(MAX_HEAP)
|
||||||
|
QSE_ASSERT (newval <= oldval);
|
||||||
|
#else
|
||||||
|
QSE_ASSERT (newval >= oldval);
|
||||||
|
#endif
|
||||||
jh.remove (0);
|
jh.remove (0);
|
||||||
|
oldval = newval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user