libc: Add bsearch (with a test!!)
This commit is contained in:
parent
1025248cc7
commit
c6ce7a5358
@ -116,7 +116,10 @@ extern "C"
|
|||||||
/* Sorts the array pointed to by base of nmemb items of the specified size using the comparison function compar. */
|
/* 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 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.
|
/* Searches the sorted array base of nmemb items of the specified size for the given key using the comparison
|
||||||
|
* function compar. */
|
||||||
|
void* bsearch(const void* key, const void* base, size_t nmemb, size_t size,
|
||||||
|
int (*compar)(const void*, const void*));
|
||||||
|
|
||||||
size_t mbstowcs(wchar_t* dest, const char* src,
|
size_t mbstowcs(wchar_t* dest, const char* src,
|
||||||
size_t n); // Not implemented.
|
size_t n); // Not implemented.
|
||||||
|
@ -122,6 +122,26 @@ static void quicksort(void* base, size_t start, size_t end, size_t size, int (*c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* binary_search(const void* key, const 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 (const void*)((const char*)base + (index * size)); };
|
||||||
|
|
||||||
|
if (end >= start)
|
||||||
|
{
|
||||||
|
size_t middle = start + (end - start) / 2;
|
||||||
|
int rc = compar(atindex(middle), key);
|
||||||
|
|
||||||
|
if (rc == 0) return const_cast<void*>(atindex(middle)); // we found it!!
|
||||||
|
|
||||||
|
if (rc < 0) return binary_search(key, base, middle + 1, end, size, compar);
|
||||||
|
|
||||||
|
return binary_search(key, base, start, middle - 1, size, compar);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
__lc_noreturn void abort()
|
__lc_noreturn void abort()
|
||||||
@ -225,9 +245,9 @@ extern "C"
|
|||||||
quicksort(base, 0, nmemb - 1, size, compar);
|
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* key, const void* base, size_t nmemb, size_t size, int (*compar)(const void*, const void*))
|
||||||
{
|
{
|
||||||
NOT_IMPLEMENTED("bsearch");
|
return binary_search(key, base, 0, nmemb - 1, size, compar);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t mbstowcs(wchar_t*, const char*, size_t)
|
size_t mbstowcs(wchar_t*, const char*, size_t)
|
||||||
|
@ -26,6 +26,7 @@ DEFINE_TEST(malloc);
|
|||||||
DEFINE_TEST(calloc);
|
DEFINE_TEST(calloc);
|
||||||
DEFINE_TEST(mktemp);
|
DEFINE_TEST(mktemp);
|
||||||
DEFINE_TEST(qsort);
|
DEFINE_TEST(qsort);
|
||||||
|
DEFINE_TEST(bsearch);
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
@ -55,4 +56,5 @@ int main()
|
|||||||
RUN_TEST(calloc);
|
RUN_TEST(calloc);
|
||||||
RUN_TEST(mktemp);
|
RUN_TEST(mktemp);
|
||||||
RUN_TEST(qsort);
|
RUN_TEST(qsort);
|
||||||
|
RUN_TEST(bsearch);
|
||||||
}
|
}
|
@ -207,3 +207,28 @@ DEFINE_TEST(qsort)
|
|||||||
|
|
||||||
TEST_SUCCESS();
|
TEST_SUCCESS();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFINE_TEST(bsearch)
|
||||||
|
{
|
||||||
|
START_TEST(bsearch);
|
||||||
|
|
||||||
|
const char sorted[] = "abcdefjkl";
|
||||||
|
char key = 'j';
|
||||||
|
|
||||||
|
char* ptr = bsearch(&key, sorted, 9, sizeof(char), compare_char); // try with sorted array first
|
||||||
|
|
||||||
|
EXPECT_EQ(*ptr, 'j');
|
||||||
|
EXPECT_EQ(ptr, &sorted[6]);
|
||||||
|
|
||||||
|
int unsorted[] = {1500, 45, 3, 11, 41, 90, 6, 32, 5, 76};
|
||||||
|
qsort(unsorted, 10, sizeof(int), compare_int);
|
||||||
|
|
||||||
|
int key2 = 90;
|
||||||
|
|
||||||
|
int* ptr2 = bsearch(&key2, unsorted, 10, sizeof(int), compare_int);
|
||||||
|
|
||||||
|
EXPECT_EQ(*ptr2, 90);
|
||||||
|
EXPECT_EQ(ptr2, &unsorted[8]);
|
||||||
|
|
||||||
|
TEST_SUCCESS();
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user