tupperware: vector: use more robust partition
This one is less efficient, doing up to N comparisons. However it is not vulnerable to the pivot being at the end or beginning of the input...
This commit is contained in:
parent
efd612e0ff
commit
0888e21150
26
src/vector.c
26
src/vector.c
|
@ -492,24 +492,18 @@ static size_t pivot_median3_between(struct vector *v,
|
||||||
|
|
||||||
static size_t partition_between(struct vector *v, size_t pivot,
|
static size_t partition_between(struct vector *v, size_t pivot,
|
||||||
vector_cmp_f cmp, void *cookie, struct sort_params *params) {
|
vector_cmp_f cmp, void *cookie, struct sort_params *params) {
|
||||||
size_t i = params->begin;
|
size_t l = params->begin;
|
||||||
size_t j = params->end;
|
size_t r = params->end;
|
||||||
void *p_val = VEC_AT(v, pivot);
|
swap_using(v, pivot, --r, params->buffer); // Put pivot at the end
|
||||||
while (1) {
|
void *p_val = VEC_AT(v, r);
|
||||||
while (cmp(VEC_AT(v, i), p_val, cookie) < 0) {
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
do
|
|
||||||
{
|
|
||||||
j--;
|
|
||||||
} while (cmp(VEC_AT(v, j), p_val, cookie) > 0);
|
|
||||||
|
|
||||||
if (i < j) {
|
for (size_t i = l; i < r; ++i) {
|
||||||
swap_using(v, i, j, params->buffer);
|
if (cmp(VEC_AT(v, i), p_val, cookie) < 0)
|
||||||
}
|
swap_using(v, i, l++, params->buffer);
|
||||||
else
|
|
||||||
return i + (params->begin == i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
swap_using(v, l, r, params->buffer); // Put it back where it needs to be
|
||||||
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SMALL_THRESHOLD 10
|
#define SMALL_THRESHOLD 10
|
||||||
|
|
Loading…
Reference in a new issue