mirror of
https://gitee.com/apaki/unicstl.git
synced 2026-05-28 22:54:19 +08:00
feat(algo): 新增算法模块并给darray集成排序和查找功能,index底层改为调用search
This commit is contained in:
parent
f8ba5197a8
commit
d36346ce00
78
include/algo.h
Normal file
78
include/algo.h
Normal file
@ -0,0 +1,78 @@
|
||||
/**
|
||||
* @file algo.h
|
||||
* @author wenjf (Orig5826@163.com)
|
||||
* @brief
|
||||
* @version 0.1
|
||||
* @date 2026-05-14
|
||||
*
|
||||
* @copyright Copyright (c) 2026
|
||||
*
|
||||
*/
|
||||
#ifndef _ALGO_H_
|
||||
#define _ALGO_H_
|
||||
|
||||
#include "unicstl_internal.h"
|
||||
|
||||
static inline void obj_swap(const void *base, size_t index, void *obj, size_t obj_size)
|
||||
{
|
||||
//...
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------
|
||||
// 排序算法
|
||||
// void __cdecl qsort(void *_Base,size_t _NumOfElements,size_t _SizeOfElements,int (__cdecl *_PtFuncCompare)(const void *,const void *));
|
||||
// --------------------------------------------------
|
||||
// 1. 冒泡排序
|
||||
bool bubble_sort(void* base, size_t count, size_t obj_size, compare_fun_t cmp);
|
||||
// 2. 插入排序
|
||||
bool insert_sort(void* base, size_t count, size_t obj_size, compare_fun_t cmp);
|
||||
// 3. 快速排序
|
||||
bool quick_sort(void* base, size_t count, size_t obj_size, compare_fun_t cmp);
|
||||
// 4. 堆排序
|
||||
bool heap_sort(void* base, size_t count, size_t obj_size, compare_fun_t cmp);
|
||||
// 5. 归并排序
|
||||
bool merge_sort(void* base, size_t count, size_t obj_size, compare_fun_t cmp);
|
||||
// 6. 选择排序
|
||||
bool select_sort(void* base, size_t count, size_t obj_size, compare_fun_t cmp);
|
||||
// 7. 希尔排序
|
||||
bool shell_sort(void* base, size_t count, size_t obj_size, compare_fun_t cmp);
|
||||
|
||||
// 非比较类排序
|
||||
// 8. 基数排序
|
||||
bool radix_sort(void* base, size_t count, size_t obj_size);
|
||||
// 9. 桶排序
|
||||
bool bucket_sort(void* base, size_t count, size_t obj_size);
|
||||
// 10. 计数排序
|
||||
bool counting_sort(void* base, size_t count, size_t obj_size);
|
||||
|
||||
// --------------------------------------------------
|
||||
// 查找算法
|
||||
// void *__cdecl bsearch(const void *_Key,const void *_Base,size_t _NumOfElements,size_t _SizeOfElements,int (__cdecl *_PtFuncCompare)(const void *,const void *));
|
||||
// --------------------------------------------------
|
||||
// 1. 线性查找
|
||||
int linear_search(const void* key, const void* base, size_t count, size_t obj_size, compare_fun_t cmp);
|
||||
|
||||
// 2. 二分查找(默认左边界)
|
||||
int binary_search(const void* key, const void* base, size_t count, size_t obj_size, compare_fun_t cmp);
|
||||
// 3. 二分查找(右边界)
|
||||
int binary_search_right(const void* key, const void* base, size_t count, size_t obj_size, compare_fun_t cmp);
|
||||
|
||||
|
||||
#ifdef UNICSTL_ALGO
|
||||
|
||||
#ifdef UNICSTL_SORT
|
||||
#define unicstl_sort(base, count, obj_size, cmp) \
|
||||
quick_sort(base, count, obj_size, cmp)
|
||||
#endif // UNICSTL_SORT
|
||||
|
||||
#ifdef UNICSTL_BSEARCH
|
||||
#define unicstl_search(base, count, obj_size, key, cmp) \
|
||||
binary_search(base, count, obj_size, key, cmp)
|
||||
#endif // UNICSTL_BSEARCH
|
||||
|
||||
#else
|
||||
|
||||
#endif // UNICSTL_ALGO
|
||||
|
||||
#endif // _ALGO_H_
|
||||
@ -29,6 +29,8 @@ struct _darray
|
||||
size_t _size;
|
||||
size_t _capacity;
|
||||
|
||||
bool _sorted;
|
||||
|
||||
struct _iterator _iter;
|
||||
void (*_destory)(struct _darray *self);
|
||||
|
||||
@ -45,9 +47,6 @@ struct _darray
|
||||
|
||||
const void* (*at)(struct _darray *self, size_t index); // O(1)
|
||||
|
||||
size_t (*index)(struct _darray *self, const void *obj); // O(n) retval -1 if not found
|
||||
bool (*contains)(struct _darray *self, const void *obj); // O(n)
|
||||
|
||||
// base
|
||||
bool (*resize)(struct _darray *self, size_t capacity);
|
||||
size_t (*size)(struct _darray *self);
|
||||
@ -56,6 +55,16 @@ struct _darray
|
||||
bool (*full)(struct _darray *self);
|
||||
bool (*clear)(struct _darray *self);
|
||||
|
||||
// sort and search
|
||||
size_t (*index)(struct _darray *self, const void *obj); // O(n) return (size_t)-1 if not found
|
||||
bool (*contains)(struct _darray *self, const void *obj); // O(n)
|
||||
|
||||
bool (*sort)(struct _darray *self); // O(nlogn)
|
||||
size_t (*search)(struct _darray *self, const void *obj); // O(n) if not sorted; O(logn) if sorted
|
||||
// return leftmost matched index; return (size_t)-1 if not found
|
||||
|
||||
size_t (*count)(struct _darray *self, const void *obj); // O(nlogn) if sorted; O(n) if not sorted
|
||||
|
||||
// iter
|
||||
iterator_t (*iter)(struct _darray *self, enum _darray_order order);
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
*/
|
||||
#ifndef _UNICSTL_CONFIG_H_
|
||||
|
||||
// #define NDEBUG // release
|
||||
#define NDEBUG // release mode if define NDEBUG
|
||||
|
||||
/**
|
||||
* @brief unicstl contains which module
|
||||
|
||||
101
src/algo.c
Normal file
101
src/algo.c
Normal file
@ -0,0 +1,101 @@
|
||||
/**
|
||||
* @file algo.c
|
||||
* @author wenjf (Orig5826@163.com)
|
||||
* @brief
|
||||
* @version 0.1
|
||||
* @date 2026-05-14
|
||||
*
|
||||
* @copyright Copyright (c) 2026
|
||||
*
|
||||
*/
|
||||
#include "algo.h"
|
||||
|
||||
// 1. 冒泡排序
|
||||
bool bubble_sort(void* base, size_t count, size_t obj_size, compare_fun_t cmp)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 2. 插入排序
|
||||
bool insert_sort(void* base, size_t count, size_t obj_size, compare_fun_t cmp)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 3. 快速排序
|
||||
bool quick_sort(void* base, size_t count, size_t obj_size, compare_fun_t cmp)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 4. 堆排序
|
||||
bool heap_sort(void* base, size_t count, size_t obj_size, compare_fun_t cmp)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 5. 归并排序
|
||||
bool merge_sort(void* base, size_t count, size_t obj_size, compare_fun_t cmp)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 6. 选择排序
|
||||
bool select_sort(void* base, size_t count, size_t obj_size, compare_fun_t cmp)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 7. 希尔排序
|
||||
bool shell_sort(void* base, size_t count, size_t obj_size, compare_fun_t cmp)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 8. 基数排序
|
||||
bool radix_sort(void* base, size_t count, size_t obj_size)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 9. 桶排序
|
||||
bool bucket_sort(void* base, size_t count, size_t obj_size)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 10. 计数排序
|
||||
bool counting_sort(void* base, size_t count, size_t obj_size)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int linear_search(const void* key, const void* base, size_t count, size_t obj_size, compare_fun_t cmp)
|
||||
{
|
||||
if (key == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < count; i++)
|
||||
{
|
||||
if (cmp((const char *)base + i * obj_size, (const char *)key) == 0)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 2. 二分查找(默认左边界)
|
||||
int binary_search(const void* key, const void* base, size_t count, size_t obj_size, compare_fun_t cmp)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// 3. 二分找右边界:右边界
|
||||
int binary_search_right(const void* key, const void* base, size_t count, size_t obj_size, compare_fun_t cmp)
|
||||
{
|
||||
|
||||
}
|
||||
112
src/darray.c
112
src/darray.c
@ -9,6 +9,7 @@
|
||||
*
|
||||
*/
|
||||
#include "darray.h"
|
||||
#include "algo.h"
|
||||
|
||||
static size_t darray_size(struct _darray *self)
|
||||
{
|
||||
@ -120,6 +121,8 @@ static bool darray_insert(struct _darray *self, size_t index, const void *obj)
|
||||
// copy new data
|
||||
memmove((char *)self->obj + offset, obj, self->_obj_size);
|
||||
self->_size += 1;
|
||||
|
||||
self->_sorted = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -188,30 +191,6 @@ const void *darray_at(struct _darray *self, size_t index)
|
||||
return (const char *)self->obj + offset;
|
||||
}
|
||||
|
||||
static size_t darray_index(struct _darray *self, const void *obj)
|
||||
{
|
||||
unicstl_assert(self != NULL);
|
||||
if (obj == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < self->size(self); ++i)
|
||||
{
|
||||
if (self->compare((const char *)self->obj + i * self->_obj_size, (const char *)obj) == 0)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static bool darray_contains(struct _darray *self, const void *obj)
|
||||
{
|
||||
unicstl_assert(self != NULL);
|
||||
return darray_index(self, obj) != -1;
|
||||
}
|
||||
|
||||
bool darray_iter_hasnext(struct _iterator *iter)
|
||||
{
|
||||
unicstl_assert(iter != NULL);
|
||||
@ -277,6 +256,85 @@ iterator_t darray_iter(struct _darray *self, enum _darray_order order)
|
||||
return iter;
|
||||
}
|
||||
|
||||
static size_t darray_index(struct _darray *self, const void *obj)
|
||||
{
|
||||
unicstl_assert(self != NULL);
|
||||
return self->search(self, obj);
|
||||
}
|
||||
|
||||
static bool darray_contains(struct _darray *self, const void *obj)
|
||||
{
|
||||
unicstl_assert(self != NULL);
|
||||
return self->search(self, obj) != (size_t)-1;
|
||||
}
|
||||
|
||||
static bool darry_sort(struct _darray *self)
|
||||
{
|
||||
unicstl_assert(self != NULL);
|
||||
if(self->_sorted)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#ifdef UNICSTL_SORT
|
||||
bubble_sort(self->obj, self->size(self), self->_obj_size, self->compare);
|
||||
#else
|
||||
qsort(self->obj, self->size(self), self->_obj_size, self->compare);
|
||||
#endif
|
||||
self->_sorted = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
static size_t darry_search(struct _darray *self, const void *obj)
|
||||
{
|
||||
unicstl_assert(self != NULL);
|
||||
if(obj == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
#ifdef UNICSTL_BSEARCH
|
||||
if(self->_sorted)
|
||||
{
|
||||
return unicstl_search(obj, self->obj, self->size(self), self->_obj_size, self->compare);
|
||||
}
|
||||
#else
|
||||
if(self->_sorted)
|
||||
{
|
||||
bsearch(obj, self->obj, self->size(self), self->_obj_size, self->compare);
|
||||
}
|
||||
#endif
|
||||
return linear_search(obj, self->obj, self->size(self), self->_obj_size, self->compare);
|
||||
}
|
||||
|
||||
static size_t darry_count(struct _darray *self, const void *obj)
|
||||
{
|
||||
unicstl_assert(self != NULL);
|
||||
if(obj == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
size_t count = 0;
|
||||
size_t index = 0;
|
||||
|
||||
if(self->_sorted)
|
||||
{
|
||||
size_t index = self->search(self, obj);
|
||||
if(index == (size_t)-1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
for(size_t i = index; i < self->size(self); i++)
|
||||
{
|
||||
if (self->compare((const char *)self->obj + i * self->_obj_size, (const char *)obj) != 0)
|
||||
{
|
||||
break;
|
||||
|
||||
}
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
static bool darray_init(struct _darray *self, size_t obj_size, size_t capacity)
|
||||
{
|
||||
unicstl_assert(self != NULL);
|
||||
@ -287,6 +345,8 @@ static bool darray_init(struct _darray *self, size_t obj_size, size_t capacity)
|
||||
self->_size = 0;
|
||||
self->_capacity = capacity;
|
||||
|
||||
self->_sorted = false;
|
||||
|
||||
self->obj = NULL;
|
||||
self->_destory = darray_destory;
|
||||
|
||||
@ -314,6 +374,10 @@ static bool darray_init(struct _darray *self, size_t obj_size, size_t capacity)
|
||||
// iter
|
||||
self->iter = darray_iter;
|
||||
|
||||
// sort and search
|
||||
self->sort = darry_sort;
|
||||
self->search = darry_search;
|
||||
|
||||
// -------------------- default --------------------
|
||||
self->print_obj = default_print_obj;
|
||||
|
||||
|
||||
@ -571,6 +571,59 @@ static void test_darray_clear(void)
|
||||
darray_free(&darray);
|
||||
}
|
||||
|
||||
static void test_darray_sort(void)
|
||||
{
|
||||
int temp = 0;
|
||||
int data[] = { 1,2,3,4,5,6,7,8,9,10 };
|
||||
size_t len = sizeof(data) / sizeof(data[0]);
|
||||
size_t i = 0;
|
||||
int unordered_data[] = { 1, 3, 4, 5, 2, 9, 8, 10, 7, 6};
|
||||
|
||||
darray_t darray = darray_new(sizeof(int), len);
|
||||
darray->compare = compare_num;
|
||||
darray->print_obj = print_num;
|
||||
|
||||
for(i = 0; i < len; i++)
|
||||
{
|
||||
darray->append(darray, &unordered_data[i]);
|
||||
}
|
||||
TEST_ASSERT_TRUE(darray->sort(darray));
|
||||
|
||||
iterator_t iter = darray->iter(darray, DARRAY_FORWARD);
|
||||
i = 0;
|
||||
while(iter->hasnext(iter))
|
||||
{
|
||||
temp = *(int *)iter->next(iter);
|
||||
TEST_ASSERT_EQUAL_INT(data[i], temp);
|
||||
i++;
|
||||
}
|
||||
TEST_ASSERT_EQUAL_INT(len, i);
|
||||
|
||||
temp = -55;
|
||||
TEST_ASSERT_TRUE(darray->append(darray, &temp));
|
||||
|
||||
TEST_ASSERT_TRUE(darray->sort(darray));
|
||||
|
||||
iter = darray->iter(darray, DARRAY_FORWARD);
|
||||
i = 0;
|
||||
while(iter->hasnext(iter))
|
||||
{
|
||||
temp = *(int *)iter->next(iter);
|
||||
if(i == 0)
|
||||
{
|
||||
TEST_ASSERT_EQUAL_INT(-55, temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
TEST_ASSERT_EQUAL_INT(data[i - 1], temp);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
TEST_ASSERT_EQUAL_INT(len + 1, i);
|
||||
|
||||
darray_free(&darray);
|
||||
}
|
||||
|
||||
static void test_darray_struct(void)
|
||||
{
|
||||
size_t i = 0;
|
||||
@ -638,7 +691,7 @@ void test_darray(void)
|
||||
RUN_TEST(test_darray_resize);
|
||||
RUN_TEST(test_darray_resize_invalid);
|
||||
|
||||
RUN_TEST(test_darray_index);
|
||||
RUN_TEST(test_darray_index); // index, search, contains
|
||||
RUN_TEST(test_darray_index_invalid);
|
||||
|
||||
RUN_TEST(test_darray_at);
|
||||
@ -647,6 +700,8 @@ void test_darray(void)
|
||||
|
||||
RUN_TEST(test_darray_iter);
|
||||
|
||||
RUN_TEST(test_darray_sort);
|
||||
|
||||
// ---------- base ----------
|
||||
RUN_TEST(test_darray_clear);
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user