libc: Add qsort (with a test!!)
This commit is contained in:
parent
44815b08c7
commit
1025248cc7
@ -113,7 +113,8 @@ extern "C"
|
|||||||
/* Runs a shell command. */
|
/* Runs a shell command. */
|
||||||
int system(const char* command);
|
int system(const char* command);
|
||||||
|
|
||||||
void qsort(void*, size_t, size_t, int (*)(const void*, const void*)); // Not implemented.
|
/* Sorts the array pointed to by base of nmemb items of the specified size using the comparison function compar. */
|
||||||
|
void qsort(void* base, size_t nmemb, size_t size, int (*compar)(const void*, const void*));
|
||||||
|
|
||||||
void* bsearch(const void*, const void*, size_t, size_t, int (*)(const void*, const void*)); // Not implemented.
|
void* bsearch(const void*, const void*, size_t, size_t, int (*)(const void*, const void*)); // Not implemented.
|
||||||
|
|
||||||
|
@ -77,6 +77,51 @@ template <typename Arg, typename Struct> static inline Struct common_div(Arg a,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void qswap(void* ptr1, void* ptr2, size_t size)
|
||||||
|
{
|
||||||
|
char* x = (char*)ptr1;
|
||||||
|
char* y = (char*)ptr2;
|
||||||
|
|
||||||
|
while (size--)
|
||||||
|
{
|
||||||
|
char t = *x;
|
||||||
|
*x = *y;
|
||||||
|
*y = t;
|
||||||
|
x += 1;
|
||||||
|
y += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t partition(void* base, size_t start, size_t end, size_t size, int (*compar)(const void*, const void*))
|
||||||
|
{
|
||||||
|
auto atindex = [&base, &size](size_t index) { return (void*)((char*)base + (index * size)); };
|
||||||
|
|
||||||
|
void* pivot = atindex(end);
|
||||||
|
size_t i = (start - 1);
|
||||||
|
|
||||||
|
for (size_t j = start; j <= end - 1; j++)
|
||||||
|
{
|
||||||
|
if (compar(atindex(j), pivot) < 0)
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
qswap(atindex(i), atindex(j), size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
qswap(atindex(i + 1), pivot, size);
|
||||||
|
return i + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void quicksort(void* base, size_t start, size_t end, size_t size, int (*compar)(const void*, const void*))
|
||||||
|
{
|
||||||
|
if (start < end)
|
||||||
|
{
|
||||||
|
size_t pivot = partition(base, start, end, size, compar);
|
||||||
|
quicksort(base, start, pivot - 1, size, compar);
|
||||||
|
quicksort(base, pivot + 1, end, size, compar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
__lc_noreturn void abort()
|
__lc_noreturn void abort()
|
||||||
@ -175,9 +220,9 @@ extern "C"
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
void qsort(void*, size_t, size_t, int (*)(const void*, const void*))
|
void qsort(void* base, size_t nmemb, size_t size, int (*compar)(const void*, const void*))
|
||||||
{
|
{
|
||||||
NOT_IMPLEMENTED("qsort");
|
quicksort(base, 0, nmemb - 1, size, compar);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* bsearch(const void*, const void*, size_t, size_t, int (*)(const void*, const void*))
|
void* bsearch(const void*, const void*, size_t, size_t, int (*)(const void*, const void*))
|
||||||
|
@ -25,6 +25,7 @@ DEFINE_TEST(srand);
|
|||||||
DEFINE_TEST(malloc);
|
DEFINE_TEST(malloc);
|
||||||
DEFINE_TEST(calloc);
|
DEFINE_TEST(calloc);
|
||||||
DEFINE_TEST(mktemp);
|
DEFINE_TEST(mktemp);
|
||||||
|
DEFINE_TEST(qsort);
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
@ -53,4 +54,5 @@ int main()
|
|||||||
RUN_TEST(malloc);
|
RUN_TEST(malloc);
|
||||||
RUN_TEST(calloc);
|
RUN_TEST(calloc);
|
||||||
RUN_TEST(mktemp);
|
RUN_TEST(mktemp);
|
||||||
|
RUN_TEST(qsort);
|
||||||
}
|
}
|
@ -164,3 +164,46 @@ DEFINE_TEST(mktemp)
|
|||||||
|
|
||||||
TEST_SUCCESS();
|
TEST_SUCCESS();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int compare_char(const void* p1, const void* p2)
|
||||||
|
{
|
||||||
|
const char* c1 = (const char*)p1;
|
||||||
|
const char* c2 = (const char*)p2;
|
||||||
|
if (*c1 < *c2) return -1;
|
||||||
|
if (*c1 > *c2) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int compare_int(const void* p1, const void* p2)
|
||||||
|
{
|
||||||
|
const int* c1 = (const int*)p1;
|
||||||
|
const int* c2 = (const int*)p2;
|
||||||
|
if (*c1 < *c2) return -1;
|
||||||
|
if (*c1 > *c2) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_TEST(qsort)
|
||||||
|
{
|
||||||
|
START_TEST(qsort);
|
||||||
|
|
||||||
|
char unsorted[] = "elacbkdjf";
|
||||||
|
const char sorted[] = "abcdefjkl";
|
||||||
|
|
||||||
|
qsort(unsorted, 9, sizeof(char), compare_char);
|
||||||
|
|
||||||
|
int rc = memcmp(sorted, unsorted, 9);
|
||||||
|
|
||||||
|
EXPECT_EQ(rc, 0);
|
||||||
|
|
||||||
|
int unsorted2[] = {1500, 45, 3, 11, 41, 90, 6, 32, 5, 76};
|
||||||
|
const int sorted2[] = {3, 5, 6, 11, 32, 41, 45, 76, 90, 1500};
|
||||||
|
|
||||||
|
qsort(unsorted2, 10, sizeof(int), compare_int);
|
||||||
|
|
||||||
|
rc = memcmp(unsorted2, sorted2, 10);
|
||||||
|
|
||||||
|
EXPECT_EQ(rc, 0);
|
||||||
|
|
||||||
|
TEST_SUCCESS();
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user