diff --git a/include/algo.h b/include/algo.h new file mode 100644 index 0000000..23cefd6 --- /dev/null +++ b/include/algo.h @@ -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_ diff --git a/include/darray.h b/include/darray.h index b6377e6..d00107c 100644 --- a/include/darray.h +++ b/include/darray.h @@ -29,13 +29,15 @@ struct _darray size_t _size; size_t _capacity; + bool _sorted; + struct _iterator _iter; void (*_destory)(struct _darray *self); // -------------------- public -------------------- // kernel - bool (*append)(struct _darray *self, const void *obj); // O(1) - bool (*pop)(struct _darray *self, void *obj); // O(1) + bool (*append)(struct _darray *self, const void *obj); // O(1) + bool (*pop)(struct _darray *self, void *obj); // O(1) bool (*insert)(struct _darray *self, size_t index, const void *obj); // O(n) bool (*remove)(struct _darray *self, size_t index, void *obj); // O(n) @@ -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); diff --git a/include/unicstl_config.h b/include/unicstl_config.h index cb1551e..443b960 100644 --- a/include/unicstl_config.h +++ b/include/unicstl_config.h @@ -10,7 +10,7 @@ */ #ifndef _UNICSTL_CONFIG_H_ -// #define NDEBUG // release +#define NDEBUG // release mode if define NDEBUG /** * @brief unicstl contains which module diff --git a/src/algo.c b/src/algo.c new file mode 100644 index 0000000..1f5fca0 --- /dev/null +++ b/src/algo.c @@ -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) +{ + +} diff --git a/src/darray.c b/src/darray.c index a818d2d..bc6f1ea 100644 --- a/src/darray.c +++ b/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; diff --git a/test/test_darray.c b/test/test_darray.c index fc2c37e..f366bac 100644 --- a/test/test_darray.c +++ b/test/test_darray.c @@ -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);