Compare commits

...

46 Commits

Author SHA1 Message Date
32f2605656 基本上完善到我理想中的样子了 2025-04-30 15:01:55 +08:00
ccae6a9d8f 将index索引转换独立出一个函数 2025-04-30 14:53:30 +08:00
65a60df00b 修改变量 2025-04-30 14:44:04 +08:00
e5ea2efe84 改了半天才发现,原来我最初写的才是最优解 2025-04-30 14:41:10 +08:00
46caba5943 还是不对,这么处理感觉好复杂啊,是不是我全部修改为闭区间容易处理一点? 2025-04-30 14:08:10 +08:00
3f8f418d4e 逻辑相对清晰一点,还差部分逻辑没调通 2025-04-30 13:25:12 +08:00
ce9acda014 条件判断还存在问题 2025-04-30 11:45:22 +08:00
e86657d807 先正序的情况修改完成 2025-04-30 11:33:54 +08:00
d2be5d229f 原版代码测试通过 2025-04-30 11:16:23 +08:00
97ae2a54c4 添加新的测试项,并尝试slice是否可以优化的更加直观 2025-04-30 11:14:59 +08:00
802d63641c 针对start和end超出范围的处理 2025-04-30 02:18:07 +08:00
b5a83f865e 添加step=2的单元测试 2025-04-30 01:50:58 +08:00
e85e1c56f3 将切片的各种情况分开来测试 2025-04-30 01:38:06 +08:00
2dfc0b2b17 先调试通过了,后续再考虑优化 2025-04-30 01:28:37 +08:00
0f18ddf567 slice单元测试基本都添加完毕,现在可以针对性的进行修改了 2025-04-30 00:58:28 +08:00
178d0bf5b4 看起来得加一个宏定义了,专门用语处理end无限长的 2025-04-30 00:37:04 +08:00
e49f425e43 添加函数注释 2025-04-30 00:17:59 +08:00
643d601c6e 添加slice函数,但是还有两个问题没有解决 2025-04-30 00:01:37 +08:00
93c0cfbd37 添加list的slice函数 2025-04-29 22:55:12 +08:00
24844219df 添加insert和delete的单元测试 2025-04-29 22:04:22 +08:00
80f8722e2e append和pop函数复用了insert和delete,理解起来更加直观 2025-04-29 16:49:54 +08:00
0c545dfca5 insert函数的bug修复完毕 2025-04-29 16:48:06 +08:00
c8a48e6c63 想统一inset和pop但是编译测试不通 2025-04-29 16:25:27 +08:00
851f815120 修改list相关接口描述以及调通由于删除deque的接口导致的编译问题 2025-04-29 14:53:54 +08:00
446ede15db 添加list实现原理说明 2025-04-29 11:52:15 +08:00
6fb620850e 双向队列删除非核心代码,至于其底层实现是否权衡各种场景,则后续再考虑优化。 2025-04-29 11:41:31 +08:00
51b41f46da 删除调试信息,默认不采用递归 2025-04-28 01:46:23 +08:00
4acdcf3ec7 开启assert后解决编译和测试问题 2025-04-28 00:59:03 +08:00
d9d5f052b1 tree简化插入接口 2025-04-28 00:38:59 +08:00
bad8d68180 tree简化max和min代码实现,并且添加递归宏定义 2025-04-27 23:55:41 +08:00
4530508a1b tree修改node的new和free接口函数 2025-04-27 23:36:42 +08:00
eb918955f5 将iter相关配置,包括成员函数的配置,都放在iter的初始化中 2025-04-27 13:59:14 +08:00
4aa966bb93 修改iter的parent为_container,避免理解偏差 2025-04-27 13:42:30 +08:00
c70b007386 iter的node一定是当前节点,因此cur的前缀就有些多余了 2025-04-27 12:44:47 +08:00
4691b848ef 修改iter的成员属性_cur为_index更加直观 2025-04-27 12:41:10 +08:00
1982a90a3e tree删除非必要属性,把order遍历相关的操作都放在iterator中了 2025-04-27 11:43:57 +08:00
d278ef008f tree_order枚举类型重命名,防冲突 2025-04-27 11:41:20 +08:00
7b672b6e77 遍历中将node重命名为target更容易理解 2025-04-27 11:35:25 +08:00
6054e712e6 广度优先遍历:删除非必要代码 2025-04-27 11:28:09 +08:00
7a7af3152a _rebalance作为私有函数 2025-04-27 11:06:16 +08:00
59e5c9be71 获取树高的接口重新定义 2025-04-27 11:05:12 +08:00
932b078778 修改函数原型说明 2025-04-27 10:23:56 +08:00
1b5b69024e 在README中添加个人信息 并添加版本更新说明 2025-04-27 02:46:44 +08:00
313406970c 修改头文件的核心操作和基础操作顺序,方便一眼看出 2025-04-27 02:29:09 +08:00
4c6387427b 在README中添加函数原型 2025-04-27 02:06:07 +08:00
ca4ab10123 deque区分正向和反向遍历 2025-04-27 01:16:22 +08:00
25 changed files with 1591 additions and 1034 deletions

View File

@ -26,6 +26,9 @@
"graph.h": "c",
"unicstl_config.h": "c",
"iter.h": "c",
"iterator.h": "c"
"iterator.h": "c",
"assert.h": "c",
"limits.h": "c",
"cstdint": "c"
}
}

102
README.md
View File

@ -1,13 +1,19 @@
# unicstl
## 简介
全称: Universal C standard library
基于C语言实现的通用C库包含常用数据结构和算法。
基于C语言实现的通用C库。包含常用数据结构和算法
**全称:** Universal C standard library
> 标准:--std=c99
**作者:** 温建峰
[数据结构详细说明](https://blog.wenjianfeng.top)
**主页:** [博客](https://blog.wenjianfeng.top)
**邮箱:**[orig5826@163.com](mailto:orig5826@163.com)
## 编译环境
- 编译器gcc 13.2.0
- 标准:--std=c99
## 数据结构
|数据结构 | 原理 |说明 |
@ -27,12 +33,80 @@
| tree_rb_new | 二叉搜索树 | 红黑树 |
| **heap** | |**堆** |
| heap_new2 | 数组 | 最大堆/最小堆 |
| **graph** | |**图** |
| graph_new | 链表 | |
## 接口函数原型
```c
// -------------------- 初始化 --------------------
struct* new(...); // 创建
void free(struct**); // 释放
// 内部接口
// init 初始化 <构造函数>
// destory 销毁 <析构函数>
// 外部实现
int compare(void* obj1, void* obj2);// 比较函数new后立刻配置树、图必须
// -------------------- 核心功能 --------------------
// 核心操作
bool push(const void* obj); // [栈、队列] 入栈/入队
bool push_front(const void* obj); // [双端队列] 头部入队
bool push_back(const void* obj); // [双端队列] 尾部入队
bool pop(void* obj); // [栈、队列] 出栈/出队
bool pop_front(void* obj); // [双端队列] 头部出队
bool pop_back(void* obj); // [双端队列] 尾部出队
bool peek(void* obj); // [栈] 查看栈顶元素
bool front(void* obj); // [队列、双端队列] 查看头部元素
bool back(void* obj); // [队列、双端队列] 查看尾部元素
// bool insert(const void* obj); // [树] 插入元素 <insert用于和位置相关操作>
// bool delete(const void* obj); // [树] 删除元素
// bool add_(const void* obj); // [图:顶点、边] 添加元素 <add不考虑位置关系>
// bool del_(const void* obj); // [图:顶点、边] 删除元素
// bool find_(const void* obj); // [图:顶点、边] 查找元素
// 基础操作
uint32_t size(); // 获取大小
bool empty(); // 判断是否为空
bool full(); // 判断是否为满
void clear(); // 清空
uint32_t capacity(); // [动态数组] 获取容量
// 迭代器操作
iterator_t iter(...); // 返回迭代器
bool iter_hasnext(); // 是否有下一个元素
void* iter_next(); // 迭代器下一个元素
// -------------------- 扩展功能 --------------------
// 元素相关操作
bool append(const void* obj); // 追加元素 <push_back> 一般用于list
// bool remove(const void *obj); // 删除元素 <暂不使用该命名>
bool find(const void* obj); // 查找元素 <返回值bool/uint32_t/void*待定>
bool contains(const void* obj); // 判断元素是否存在 <返回bool>
uint32_t count(const void* obj); // 统计元素obj的个数
// 索引相关操作
uint32_t index(void *obj); // 获取元素索引
bool insert(uint32_t index, const void* obj); // 插入元素 <非树>
bool delete(uint32_t index, void* obj); // 删除元素
// bool erase(uint32_t index); // 删除元素<暂时不用该命名>
bool set(uint32_t index, const void* obj); // 设置元素
bool get(uint32_t index, void* obj); // 获取元素
```
## 特点
| 原理 | 说明 |
| --- | --- |
| 链表 | 有额外指针开销 |
| 动态数组 | 扩容时数据搬移代价较大 |
| 原理 | 优势 | 弊端 |
| --- | --- |--- |
| 链表 | 插入删除效率高 | 有额外指针开销 |
| 动态数组 | 随机访问效率高 | 扩容时数据搬移代价较大 |
| --- | --- | --- |
| 单链表 | 适用内存受限场景 | 逆向不便 |
| 双向链表 | 频繁双向遍历的场景(如光标移动) | 空间开销大 |
## 性能比较
@ -91,6 +165,18 @@ unicstl_stack_v1.2.5_20240717-a0.zip
## 修改日志
### Unicstl 0.0.02 (2025-04-24)
- new features
- graph add function: add/del/find vertex/edge
- graph add function: bfs/dfs
- tree remove old iterator and add new iterator
- deque add order select
- bugfixed:
- none
- others:
- none
### Unicstl 0.0.01 (2025-04-24)
- new features
- add stack

View File

@ -140,6 +140,7 @@ static void demo_deque_num(void)
}
}
#if 0
printf("----- push_front -----\n");
for (i = 0; i < len; i++)
{
@ -173,6 +174,7 @@ static void demo_deque_num(void)
printf("\n");
}
}
#endif
deque_free(&deque);
}
@ -334,7 +336,6 @@ static void demo_deque_struct(void)
printf("----- print -----\n");
deque->print(deque);
printf("\n");
#endif
printf("----- get -----\n");
for (i = 0; i < len; i++)
@ -346,6 +347,7 @@ static void demo_deque_struct(void)
printf("\n");
}
}
#endif
deque_free(&deque);
}

View File

@ -32,15 +32,15 @@ static void demo_list_num(void)
printf("\n");
printf("----- pop -----\n");
list->pop(list, 9, NULL);
list->delete(list, 9, NULL);
list->print(list);
printf("\n");
list->pop(list, 0, NULL);
list->delete(list, 0, NULL);
list->print(list);
printf("\n");
list->pop(list, 4, NULL);
list->delete(list, 4, NULL);
list->print(list);
printf("\n");
@ -129,7 +129,7 @@ static void demo_list_num(void)
printf("----- pop -----\n");
for (i = 0; i < len + 1; i++)
{
list->pop(list, 0, &temp);
list->pop(list, &temp);
if (list->empty(list))
{
@ -167,15 +167,15 @@ static void demo_list_struct(void)
printf("\n");
printf("----- pop -----\n");
list->pop(list, 9, NULL);
list->delete(list, 9, NULL);
list->print(list);
printf("\n");
list->pop(list, 0, NULL);
list->delete(list, 0, NULL);
list->print(list);
printf("\n");
list->pop(list, 4, NULL);
list->delete(list, 4, NULL);
list->print(list);
printf("\n");
@ -286,7 +286,7 @@ static void demo_list_struct(void)
printf("----- pop -----\n");
for (i = 0; i < len + 1; i++)
{
list->pop(list, 0, &temp);
list->pop(list, &temp);
if (list->empty(list))
{

View File

@ -39,4 +39,9 @@
*/
typedef int (*compare_fun_t)(void* obj, void* obj2);
// default function
int default_compare(void* obj1, void* obj2);
void default_print_obj(void* obj);
#endif // _COMMON_H_

View File

@ -13,6 +13,12 @@
#include "common.h"
enum _deque_order
{
DEQUE_FORWARD,
DEQUE_REVERSE,
};
struct _deque_node
{
void* obj;
@ -43,28 +49,14 @@ struct _deque
bool (*pop_front)(struct _deque* self, void* obj);
bool (*back)(struct _deque* self, void* obj);
bool (*front)(struct _deque* self, void* obj);
bool (*empty)(struct _deque* self);
// base
uint32_t(*size)(struct _deque* self);
bool (*clear)(struct _deque* self);
bool (*empty)(struct _deque* self);
// iter
iterator_t (*iter)(struct _deque* self);
// ohters
bool (*insert)(struct _deque* self, int index, void* obj);
bool (*erase)(struct _deque* self, int index, void* obj);
int (*index)(struct _deque* self, void* obj);
bool (*remove)(struct _deque* self, void* obj);
bool (*get)(struct _deque* self, int index, void* obj);
bool (*set)(struct _deque* self, int index, void* obj);
// compare
// int (*compare)(void* obj, void* obj2);
// bool (*sort)(struct _deque* self, uint8_t reserve);
iterator_t (*iter)(struct _deque* self, enum _deque_order order);
// -------------------- debug --------------------
void (*print)(struct _deque* self);

View File

@ -78,12 +78,11 @@ struct _graph
bool (*del_edge)(struct _graph* self, void* from, void* to);
bool (*find_edge)(struct _graph* self, void* from, void* to);
bool (*empty)(struct _graph* self);
bool (*full)(struct _graph* self);
// base
uint32_t(*size)(struct _graph* self);
uint32_t(*capacity)(struct _graph* self);
bool (*empty)(struct _graph* self);
bool (*full)(struct _graph* self);
bool (*clear)(struct _graph* self);
// iter

View File

@ -36,12 +36,12 @@ struct _heap
// -------------------- public --------------------
// kernel
bool (*peek)(struct _heap* self, void* obj);
bool (*push)(struct _heap* self, void* obj);
bool (*pop)(struct _heap* self, void* obj);
bool (*empty)(struct _heap* self);
bool (*peek)(struct _heap* self, void* obj);
// base
bool (*empty)(struct _heap* self);
uint32_t(*size)(struct _heap* self);
bool (*clear)(struct _heap* self);

View File

@ -16,9 +16,11 @@
struct _iterator
{
// ---------- private ----------
void* _parent;
void* _cur_node;
uint32_t _cur;
void* _container; // pointer to stack/queue/tree ...
void* _node; // current node
uint32_t _index; // current index
uint32_t _order;
// ---------- public ----------
bool (*hasnext)(struct _iterator* self);

View File

@ -2,6 +2,10 @@
* @file list.h
* @author wenjf (Orig5826@163.com)
* @brief
*
* @details dynamic array list.
* similar to python list/ java ArrayList / C++ std::vector
*
* @version 0.1
* @date 2024-06-23
*
@ -14,10 +18,12 @@
#include "common.h"
#include "iterator.h"
#define LIST_UNLIMITED INT32_MAX
struct _list
{
// -------------------- private --------------------
void * obj;
void *obj;
uint32_t _obj_size;
uint32_t _size;
@ -27,47 +33,47 @@ struct _list
struct _iterator _iter;
void (*_destory)(struct _list* self);
void (*_destory)(struct _list *self);
// -------------------- public --------------------
// kernel
bool (*append)(struct _list* self, void* obj); // Append object to the end of the list.
bool (*insert)(struct _list* self, int index, void* obj); // Insert object before index.
bool (*pop)(struct _list* self, int index, void* obj); // Remove and return item at index.
bool (*append)(struct _list *self, void *obj);
bool (*pop)(struct _list *self, void *obj);
int (*index)(struct _list* self, void* obj); // Return first index of obj. Return -1 if the obj is not present.
bool (*remove)(struct _list* self, void *obj); // Remove first occurrence of obj.
bool (*insert)(struct _list *self, int index, void *obj);
bool (*delete)(struct _list *self, int index, void *obj);
bool (*get)(struct _list* self, int index, void* obj);
bool (*set)(struct _list* self, int index, void* obj);
bool (*get)(struct _list *self, int index, void *obj);
bool (*set)(struct _list *self, int index, void *obj);
int (*index)(struct _list *self, void *obj); // retval -1 if not found
// bool (*contains)(struct _list *self, void *obj);
// base
uint32_t(*size)(struct _list* self);
bool (*empty)(struct _list* self);
bool (*clear)(struct _list* self);
uint32_t (*size)(struct _list *self);
uint32_t (*capacity)(struct _list *self);
bool (*empty)(struct _list *self);
bool (*clear)(struct _list *self);
// iter
iterator_t (*iter)(struct _list* self);
iterator_t (*iter)(struct _list *self);
// sort
// bool (*reverse)(struct _list* self); // Reverse *IN PLACE*.
/**
Sort the list in ascending order and return false.
The sort is in-place (i.e. the list itself is modified) and stable (i.e. the
order of two equal elements is maintained).
The reverse flag can be set to sort in descending order.
*/
// bool (*sort)(struct _list* self, uint8_t reserve, int (*compare)(void* obj, void* obj2));
// others
struct _list* (*slice)(struct _list *self, int start, int end, int step);
// struct _list* (*copy)(struct _list *self);
// config
compare_fun_t compare; // !!! you have to implement this function
// -------------------- debug --------------------
void (*print)(struct _list* self);
void (*print_obj)(void* obj);
void (*print)(struct _list *self);
void (*print_obj)(void *obj);
};
typedef struct _list* list_t;
typedef struct _list *list_t;
// create and free list
list_t list_new2(uint32_t obj_size, uint32_t capacity);
void list_free(list_t* list);
void list_free(list_t *list);
#endif // _LIST_H_

View File

@ -43,11 +43,11 @@ struct _stack
bool (*push)(struct _stack* self, void* obj);
bool (*pop)(struct _stack* self, void* obj);
bool (*peek)(struct _stack* self, void* obj);
bool (*empty)(struct _stack* self);
// base
uint32_t (*size)(struct _stack* self);
uint32_t (*capacity)(struct _stack* self);
bool (*empty)(struct _stack* self);
bool (*clear)(struct _stack* self);
// iter

View File

@ -22,29 +22,17 @@ typedef enum {
RBT_BLACK,
}rbt_color;
/**
* @brief dfs amd bfs traversal order
*
* pre-order traversal
* in-order traversal
* post-order traversal
* breadth-first search traversal [BFS]
*
* right-first pre-order traversal
* right-first in-order traversal
* right-first post-order traversal
* breadth-first search traversal [BFS]
*/
enum _order{
ORDER_PRE,
ORDER_IN,
ORDER_POST,
ORDER_BREADTH,
// dfs and bfs traversal order
enum _tree_order{
ORDER_PRE, // pre-order
ORDER_IN, // in-order
ORDER_POST, // post-order
ORDER_BREADTH, // breadth-first search [BFS]
ORDER_PRE_R,
ORDER_IN_R,
ORDER_POST_R,
ORDER_BREADTH_R,
ORDER_PRE_R, // right-first pre-order
ORDER_IN_R, // right-first in-order
ORDER_POST_R, // right-first post-order
ORDER_BREADTH_R,// right-first breadth-first search [BFS]
};
struct _tree_node
@ -71,22 +59,19 @@ struct _tree
uint32_t _capacity;
uint32_t _ratio;
enum _order _order;
bool _right_priority;
stack_t stack;
queue_t queue;
struct _iterator _iter;
bool (*_rebalance)(struct _tree* self, struct _tree_node* root);
void (*_destory)(struct _tree* self);
// -------------------- public --------------------
// kernel
bool (*insert)(struct _tree* self, void* obj);
bool (*delete)(struct _tree* self, void* obj);
bool (*rebalance)(struct _tree* self, struct _tree_node* root);
int32_t (*height)(struct _tree* self, struct _tree_node* root);
uint32_t (*height)(struct _tree* self);
// base
bool (*clear)(struct _tree* self);
@ -94,7 +79,7 @@ struct _tree
uint32_t (*size)(struct _tree* self);
// iter
iterator_t (*iter)(struct _tree* self, enum _order);
iterator_t (*iter)(struct _tree* self, enum _tree_order);
// others
bool (*min)(struct _tree* self, void* obj);

View File

@ -11,7 +11,7 @@
#ifndef _UNICSTL_CONFIG_H_
/**
* @brief unicstl container
* @brief unicstl contains which module
*
*/
#define UNICSTL_LIST
@ -27,7 +27,7 @@
* @brief debug
*
*/
#define NDEBUG // assert disable
// #define NDEBUG // assert disable
#define UNICSTL_DEBUG
@ -38,7 +38,6 @@
#define UNICSTL_DEBUG_TREE
#define UNICSTL_DEBUG_HEAP
#define UNICSTL_DEBUG_GRAPH
// #define UNICSTL_DEBUG_ITERATOR
#endif
#endif

View File

@ -198,26 +198,6 @@ static bool deque_front(struct _deque* self, void* obj)
return true;
}
static bool deque_insert(struct _deque* self, int index, void* obj)
{
return true;
}
static bool deque_erase(struct _deque* self, int index, void* obj)
{
return true;
}
static int deque_index(struct _deque* self, void* obj)
{
return -1;
}
static bool deque_remove(struct _deque* self, void* obj)
{
return true;
}
static bool deque_clear(struct _deque* self)
{
while (!self->empty(self))
@ -227,38 +207,6 @@ static bool deque_clear(struct _deque* self)
return true;
}
static bool deque_get(struct _deque* self, int index, void* obj)
{
assert(self != NULL);
assert(obj != NULL);
assert(index >= 0 && index < self->size(self));
struct _deque_node* node = self->_head; // front
for (int i = 0; i < index; i++)
{
node = node->next;
}
memmove(obj, node->obj, self->_obj_size);
return true;
}
static bool deque_set(struct _deque* self, int index, void* obj)
{
assert(self != NULL);
assert(obj != NULL);
assert(index >= 0 && index < self->size(self));
struct _deque_node* node = self->_head; // front
for (int i = 0; i < index; i++)
{
node = node->next;
}
memmove(node->obj, obj, self->_obj_size);
return true;
}
static uint32_t deque_size(struct _deque* self)
{
assert(self != NULL);
@ -295,24 +243,13 @@ static void deque_print(struct _deque* self)
}
}
iterator_t deque_iter(struct _deque* self)
{
assert(self != NULL);
iterator_t iter = &self->_iter;
iter->_parent = self;
iter->_cur = 0;
iter->_cur_node = self->_head;
return iter;
}
bool deque_iter_hasnext(struct _iterator* iter)
{
assert(iter != NULL);
assert(iter->parent != NULL);
assert(iter->_container != NULL);
deque_t self = (deque_t)iter->_parent;
if(iter->_cur < self->size(self))
deque_t self = (deque_t)iter->_container;
if(iter->_index < self->size(self))
{
return true;
}
@ -322,22 +259,53 @@ bool deque_iter_hasnext(struct _iterator* iter)
const void* deque_iter_next(struct _iterator* iter)
{
assert(iter != NULL);
assert(iter->parent != NULL);
assert(iter->_container != NULL);
deque_t self = (deque_t)iter->_parent;
deque_t self = (deque_t)iter->_container;
void *obj = NULL;
// base on linklist
struct _deque_node * node = (struct _deque_node *)iter->_cur_node;
if(node != NULL)
struct _deque_node * cur_node = (struct _deque_node *)iter->_node;
if(cur_node == NULL)
{
obj = node->obj;
iter->_cur_node = node->next;
return NULL;
}
self->_iter._cur += 1;
obj = cur_node->obj;
if(iter->_order == DEQUE_FORWARD)
{
iter->_node = cur_node->next;
}
else
{
iter->_node = cur_node->prev;
}
iter->_index += 1;
return obj;
}
iterator_t deque_iter(struct _deque* self, enum _deque_order order)
{
assert(self != NULL);
iterator_t iter = &self->_iter;
iter->_container = self;
iter->_index = 0;
iter->_order = order;
if(iter->_order == DEQUE_FORWARD)
{
iter->_node = self->_head;
}
else
{
iter->_node = self->_tail;
}
iter->hasnext = deque_iter_hasnext;
iter->next = deque_iter_next;
return iter;
}
static bool deque_init(struct _deque* self, uint32_t obj_size)
{
assert(self != NULL);
@ -354,9 +322,6 @@ static bool deque_init(struct _deque* self, uint32_t obj_size)
self->_head = NULL;
self->_tail = NULL;
self->_iter.hasnext = deque_iter_hasnext;
self->_iter.next = deque_iter_next;
self->_destory = deque_destory;
// -------------------- public --------------------
@ -367,25 +332,15 @@ static bool deque_init(struct _deque* self, uint32_t obj_size)
self->pop_front = deque_pop_front;
self->back = deque_back;
self->front = deque_front;
self->empty = deque_empty;
// base
self->clear = deque_clear;
self->size = deque_size;
self->empty = deque_empty;
// iter
self->iter = deque_iter;
// others
self->insert = deque_insert;
self->erase = deque_erase;
self->index = deque_index;
self->remove = deque_remove;
self->set = deque_set;
self->get = deque_get;
// -------------------- debug --------------------
self->print = deque_print;

View File

@ -822,59 +822,13 @@ static struct _graph_node * graph_find_next_unvisited_target(struct _graph *self
return NULL;
}
iterator_t graph_iter(struct _graph *self, enum _graph_search search_type, void *start)
{
assert(self != NULL);
iterator_t iter = &self->_iter;
iter->_parent = self;
iter->_cur = 0;
iter->_cur_node = self->_head->next;
struct _graph_node *start_node = find_node(self, start);
if (start_node == NULL)
{
goto done;
}
iter->_cur_node = start_node;
struct _graph_node *node = self->_head->next;
while (node != NULL)
{
node->visited = false;
node = node->next;
}
self->_search = search_type;
switch (self->_search)
{
case GRAPH_BFS:
{
self->queue->push(self->queue, &iter->_cur_node);
}
break;
case GRAPH_DFS:
{
// pass
}
break;
default:
{
}
break;
}
done:
return iter;
}
bool graph_iter_hasnext(struct _iterator *iter)
{
assert(iter != NULL);
assert(iter->parent != NULL);
assert(iter->_container != NULL);
graph_t self = (graph_t)iter->_parent;
if (iter->_cur < self->size(self))
graph_t self = (graph_t)iter->_container;
if (iter->_index < self->size(self))
{
return true;
}
@ -884,17 +838,16 @@ bool graph_iter_hasnext(struct _iterator *iter)
const void *graph_iter_next(struct _iterator *iter)
{
assert(iter != NULL);
assert(iter->parent != NULL);
graph_t self = (graph_t)iter->_parent;
assert(iter->_container != NULL);
graph_t self = (graph_t)iter->_container;
void *obj = NULL;
iter->_cur += 1;
iter->_index += 1;
switch (self->_search)
{
case GRAPH_BFS:
{
struct _graph_node *cur_node = iter->_cur_node;
struct _graph_node *cur_node = iter->_node;
struct _graph_edge *cur_edge = cur_node->edgehead;
struct _graph_node *target = NULL;
struct _graph_node *node = cur_node;
@ -933,14 +886,13 @@ const void *graph_iter_next(struct _iterator *iter)
cur_node = node;
}
iter->_cur_node = cur_node;
iter->_node = cur_node;
obj = cur_node->obj;
}
break;
case GRAPH_DFS:
{
// self->stack->push(self->stack, iter->_cur_node);
struct _graph_node *cur_node = self->_iter._cur_node;
struct _graph_node *cur_node = iter->_node;
struct _graph_node *node = NULL;
stack_t stack = self->stack;
@ -976,7 +928,7 @@ const void *graph_iter_next(struct _iterator *iter)
}
}
}
iter->_cur_node = cur_node;
iter->_node = cur_node;
obj = node->obj;
}
break;
@ -989,6 +941,55 @@ const void *graph_iter_next(struct _iterator *iter)
return obj;
}
iterator_t graph_iter(struct _graph *self, enum _graph_search search_type, void *start)
{
assert(self != NULL);
iterator_t iter = &self->_iter;
iter->_container = self;
iter->_index = 0;
// iter->_node = self->_head->next;
struct _graph_node *start_node = find_node(self, start);
if (start_node == NULL)
{
goto done;
}
iter->_node = start_node;
iter->hasnext = graph_iter_hasnext;
iter->next = graph_iter_next;
struct _graph_node *node = self->_head->next;
while (node != NULL)
{
node->visited = false;
node = node->next;
}
self->_search = search_type;
switch (self->_search)
{
case GRAPH_BFS:
{
self->queue->push(self->queue, &iter->_node);
}
break;
case GRAPH_DFS:
{
// pass
}
break;
default:
{
}
break;
}
done:
return iter;
}
static bool graph_init(struct _graph *self, uint32_t obj_size)
{
assert(self != NULL);
@ -1030,9 +1031,6 @@ static bool graph_init(struct _graph *self, uint32_t obj_size)
self->_type = GRAPH_UNDIRECTED;
// self->_type = GRAPH_DIRECTED;
self->_iter.hasnext = graph_iter_hasnext;
self->_iter.next = graph_iter_next;
self->_destory = graph_destory;
// -------------------- public --------------------

View File

@ -249,25 +249,13 @@ static void heap_print(struct _heap* self)
}
}
iterator_t heap_iter(struct _heap* self)
{
assert(self != NULL);
iterator_t iter = &self->_iter;
iter->_parent = self;
iter->_cur = 0;
iter->_cur_node = self->obj;
return iter;
}
bool heap_iter_hasnext(struct _iterator* iter)
{
assert(iter != NULL);
assert(iter->parent != NULL);
assert(iter->_container != NULL);
heap_t self = (heap_t)iter->_parent;
if(iter->_cur < self->size(self))
heap_t self = (heap_t)iter->_container;
if(iter->_index < self->size(self))
{
return true;
}
@ -277,18 +265,32 @@ bool heap_iter_hasnext(struct _iterator* iter)
const void* heap_iter_next(struct _iterator* iter)
{
assert(iter != NULL);
assert(iter->parent != NULL);
assert(iter->_container != NULL);
heap_t self = (heap_t)iter->_parent;
heap_t self = (heap_t)iter->_container;
void *obj = NULL;
uint32_t index = self->_iter._cur;
uint32_t index = iter->_index;
obj = self->obj + self->_obj_size * index;
self->_iter._cur += 1;
iter->_index += 1;
return obj;
}
iterator_t heap_iter(struct _heap* self)
{
assert(self != NULL);
iterator_t iter = &self->_iter;
iter->_container = self;
iter->_index = 0;
iter->_node = self->obj;
iter->hasnext = heap_iter_hasnext;
iter->next = heap_iter_next;
return iter;
}
static bool heap_init2(struct _heap* self, uint32_t obj_size, uint32_t capacity)
{
assert(self != NULL);
@ -305,9 +307,6 @@ static bool heap_init2(struct _heap* self, uint32_t obj_size, uint32_t capacity)
return false;
}
self->_iter.hasnext = heap_iter_hasnext;
self->_iter.next = heap_iter_next;
self->_destory = heap_destory;
// -------------------- public --------------------

View File

@ -10,39 +10,20 @@
*/
#include "list.h"
static bool list_append(struct _list* self, void* obj)
{
assert(self != NULL);
assert(self->obj != NULL);
assert(obj != NULL);
if (self->size(self) == self->_capacity)
{
int capacity = self->_capacity * self->_ratio;
void * obj_new = (void *)realloc(self->obj, capacity * self->_obj_size);
if (obj_new == NULL)
{
return false;
}
self->obj = obj_new;
self->_capacity = capacity;
}
uint32_t index = self->size(self);
uint32_t offset = index * self->_obj_size;
memmove((char*)self->obj + offset, obj, self->_obj_size);
self->_size += 1;
return true;
}
static bool list_insert(struct _list* self, int index, void* obj)
{
assert(index >= 0 && index < (int)self->size(self));
// assert(index >= 0 && index < (int)self->size(self));
// assert(index >= 0 && index <= (int)self->size(self));
if (index < 0 || index >(int)self->size(self))
{
return false;
}
if (self->size(self) == self->_capacity)
{
int capacity = self->_capacity * self->_ratio;
void* obj_new = (void *)realloc(self->obj, capacity * self->_obj_size);
void* obj_new = (void*)realloc(self->obj, capacity * self->_obj_size);
if (obj_new == NULL)
{
return false;
@ -52,16 +33,24 @@ static bool list_insert(struct _list* self, int index, void* obj)
}
uint32_t offset = index * self->_obj_size;
uint32_t offset1 = (index + 1) * self->_obj_size;
uint32_t count = self->size(self) - index;
memmove((char*)self->obj + offset, (char*)self->obj + offset, self->size(self) * self->_obj_size);
// move data to right
memmove((char*)self->obj + offset1, (char*)self->obj + offset, count * self->_obj_size);
// copy new data
memmove((char*)self->obj + offset, obj, self->_obj_size);
self->_size += 1;
return true;
}
static bool list_pop(struct _list* self, int index, void* obj)
static bool list_delete(struct _list* self, int index, void* obj)
{
assert(self != NULL);
assert(index >= (int)(0 - self->size(self)) && index < (int)self->size(self));
// assert(index >= (int)(0 - self->size(self)) && index < (int)self->size(self));
if (index < (int)(0 - self->size(self)) || index >= (int)self->size(self))
{
return false;
}
if (self->empty(self))
{
@ -73,9 +62,9 @@ static bool list_pop(struct _list* self, int index, void* obj)
index += self->size(self);
}
uint32_t count = self->size(self) - 1 - index;
uint32_t offset = index * self->_obj_size;
uint32_t offset1 = (index + 1) * self->_obj_size;
uint32_t count = self->size(self) - 1 - index;
if (obj != NULL)
{
memmove(obj, (char*)self->obj + offset, self->_obj_size);
@ -85,15 +74,39 @@ static bool list_pop(struct _list* self, int index, void* obj)
return true;
}
static int list_index(struct _list* self, void* obj)
static bool list_append(struct _list* self, void* obj)
{
return 0;
return self->insert(self, (int)self->size(self), obj);
}
static bool list_remove(struct _list* self, void* obj)
static bool list_pop(struct _list* self, void* obj)
{
if (self->empty(self))
{
return false;
}
return self->delete(self, (int)self->size(self) - 1, obj);
}
static int list_index(struct _list* self, void* obj)
{
assert(self != NULL);
return true;
int index = 0;
if (obj == NULL)
{
return -1;
}
while (index < (int)self->size(self))
{
if (self->compare(self->obj + index * self->_obj_size, obj) == 0)
{
return index;
}
index++;
}
return -1;
}
static bool list_clear(struct _list* self)
@ -133,25 +146,22 @@ static bool list_set(struct _list* self, int index, void* obj)
static uint32_t list_size(struct _list* self)
{
assert(self != NULL);
return self->_size;
}
static uint32_t list_capacity(struct _list* self)
{
assert(self != NULL);
return self->_capacity;
}
static bool list_empty(struct _list* self)
{
assert(self != NULL);
return !self->size(self);
}
static bool list_reverse(struct _list* self)
{
return true;
}
static bool list_sort(struct _list* self, uint8_t reserve, int (*compare)(void* obj, void* obj2))
{
return true;
}
// free
static void list_destory(struct _list* self)
{
@ -179,38 +189,185 @@ static void list_print(struct _list* self)
}
}
static const void* list_iter_next(struct _iterator* iter)
static int list_index_exchange(struct _list* self, int index)
{
list_t self = (list_t)iter->_parent;
void *obj = self->obj + self->_iter._cur * self->_obj_size;
self->_iter._cur += 1;
return obj;
assert(self != NULL);
int size = (int)self->size(self);
if (index < 0)
{
index += size;
if (index < 0)
{
index = 0;
}
}
else
{
if (index > size)
{
index = size;
}
}
return index;
}
/**
* @brief list slice
* if index < 0, from the end of list. for example:
* list[-1] is the last element in list.
*
* @param self
* @param start start index
* @param end end index
* @param step step, if step < 0, return a reverse list.
* @return struct _list*
* a copy of the list, from start to end, step by step.
* if step < 0, return a reverse list.
* if step > 0, return a forward list.
* if step == 0, return NULL.
*/
struct _list* list_slice(struct _list* self, int start, int end, int step)
{
assert(self != NULL);
int i = 0;
bool contains_last_obj = false;
int size = (int)self->size(self);
int capicity = 1;
list_t list = NULL;
if (step == 0)
{
return NULL;
}
if (step > 0)
{
if (start == LIST_UNLIMITED)
{
start = 0;
}
if (end == LIST_UNLIMITED)
{
end = size;
}
}
else
{
if (start == LIST_UNLIMITED)
{
start = size - 1;
}
if (end == LIST_UNLIMITED)
{
end = 0;
contains_last_obj = true;
}
}
start = list_index_exchange(self, start);
end = list_index_exchange(self, end);
if(abs(end - start) != 0)
{
capicity = abs(end - start);
}
list = list_new2(self->_obj_size, capicity);
if (list == NULL)
{
return NULL;
}
list->compare = self->compare;
list->print_obj = self->print_obj;
if (step > 0)
{
if (start >= end)
{
goto done;
}
if (contains_last_obj != true)
{
for (i = start; i < end; i += step)
{
list->append(list, (char*)self->obj + i * self->_obj_size);
}
}
else
{
for (i = start; i <= end; i += step)
{
list->append(list, (char*)self->obj + i * self->_obj_size);
}
}
}
else /*if(step < 0)*/
{
if (start <= end)
{
goto done;
}
if (contains_last_obj != true)
{
for (i = start; i > end; i += step)
{
list->append(list, (char*)self->obj + i * self->_obj_size);
}
}
else
{
for (i = start; i >= end; i += step)
{
list->append(list, (char*)self->obj + i * self->_obj_size);
}
}
}
done:
return list;
}
static bool list_iter_hasnext(struct _iterator* iter)
{
list_t self = (list_t)iter->_parent;
list_t self = (list_t)iter->_container;
if(self->_iter._cur < self->size(self))
if (iter->_index < self->size(self))
{
return true;
}
return false;
}
static const void* list_iter_next(struct _iterator* iter)
{
list_t self = (list_t)iter->_container;
void* obj = self->obj + iter->_index * self->_obj_size;
iter->_index += 1;
return obj;
}
iterator_t list_iter(struct _list* self)
{
self->_iter._parent = self;
self->_iter._cur = 0;
return &self->_iter;
assert(self != NULL);
iterator_t iter = &self->_iter;
iter->_container = self;
iter->_index = 0;
iter->hasnext = list_iter_hasnext;
iter->next = list_iter_next;
return iter;
}
static bool list_init2(struct _list* list, uint32_t obj_size, uint32_t capacity)
{
assert(list != NULL);
assert(obj_size > 0);
assert(capacity > 0);
if(list == NULL || obj_size == 0 || capacity == 0)
if (list == NULL || obj_size == 0 || capacity == 0)
{
return false;
}
@ -236,28 +393,33 @@ static bool list_init2(struct _list* list, uint32_t obj_size, uint32_t capacity)
// -------------------- public --------------------
// kernel
list->append = list_append;
list->insert = list_insert;
list->pop = list_pop;
list->empty = list_empty;
list->insert = list_insert;
list->delete = list_delete;
list->get = list_get;
list->set = list_set;
list->index = list_index;
// list->contains = list_contains;
// base
list->clear = list_clear;
list->size = list_size;
list->empty = list_empty;
list->capacity = list_capacity;
// iter
list->iter = list_iter;
// others
list->index = list_index;
list->remove = list_remove;
list->get = list_get;
list->set = list_set;
// list->reverse = list_reverse;
// list->sort = list_sort;
list->slice = list_slice;
// config
list->compare = default_compare;
// -------------------- debug --------------------
list->print_obj = default_print_obj;
list->print = list_print;
return true;
@ -267,12 +429,12 @@ list_t list_new2(uint32_t obj_size, uint32_t capacity)
{
struct _list* list = NULL;
list = (struct _list*)calloc(1, sizeof(struct _list));
if(list == NULL)
if (list == NULL)
{
return NULL;
}
if(list_init2(list, obj_size, capacity) != true)
if (list_init2(list, obj_size, capacity) != true)
{
free(list);
return NULL;
@ -283,9 +445,9 @@ list_t list_new2(uint32_t obj_size, uint32_t capacity)
void list_free(list_t* list)
{
assert(list != NULL);
if(list != NULL && *list != NULL)
if (list != NULL && *list != NULL)
{
if((*list)->_destory != NULL)
if ((*list)->_destory != NULL)
{
(*list)->_destory(*list);
}

View File

@ -306,24 +306,13 @@ static void queue2_print(struct _queue* self)
}
}
static iterator_t queue_iter(struct _queue* self)
{
assert(self != NULL);
iterator_t iter = &self->_iter;
iter->_parent = self;
iter->_cur = 0;
iter->_cur_node = self->_front;
return iter;
}
static bool queue_iter_hasnext(struct _iterator* iter)
{
assert(iter != NULL);
assert(iter->parent != NULL);
assert(iter->_container != NULL);
queue_t self = (queue_t)iter->_parent;
if(iter->_cur < self->size(self))
queue_t self = (queue_t)iter->_container;
if(iter->_index < self->size(self))
{
return true;
}
@ -333,42 +322,69 @@ static bool queue_iter_hasnext(struct _iterator* iter)
static const void* queue_iter_next(struct _iterator* iter)
{
assert(iter != NULL);
assert(iter->parent != NULL);
assert(iter->_container != NULL);
queue_t self = (queue_t)iter->_parent;
queue_t self = (queue_t)iter->_container;
void *obj = NULL;
// base on linklist
struct _queue_node * node = (struct _queue_node *)iter->_cur_node;
struct _queue_node * node = (struct _queue_node *)iter->_node;
if(node != NULL)
{
obj = node->obj;
iter->_cur_node = node->next;
iter->_node = node->next;
}
self->_iter._cur += 1;
iter->_index += 1;
return obj;
}
static iterator_t queue_iter(struct _queue* self)
{
assert(self != NULL);
iterator_t iter = &self->_iter;
iter->_container = self;
iter->_index = 0;
iter->_node = self->_front;
iter->hasnext = queue_iter_hasnext;
iter->next = queue_iter_next;
return iter;
}
static const void* queue2_iter_next(struct _iterator* iter)
{
assert(iter != NULL);
assert(iter->parent != NULL);
assert(iter->_container != NULL);
queue_t self = (queue_t)iter->_parent;
queue_t self = (queue_t)iter->_container;
void *obj = NULL;
// base on array
uint32_t index = self->_iter._cur;
uint32_t index = iter->_index;
obj = self->_front->obj + self->_obj_size * index;
self->_iter._cur += 1;
iter->_index += 1;
return obj;
}
static iterator_t queue2_iter(struct _queue* self)
{
assert(self != NULL);
iterator_t iter = &self->_iter;
iter->_container = self;
iter->_index = 0;
iter->_node = self->_front;
iter->hasnext = queue_iter_hasnext;
iter->next = queue2_iter_next;
return iter;
}
static bool queue_init(struct _queue * self, uint32_t obj_size)
{
assert(self != NULL);
assert(obj_size > 0);
if(self == NULL || obj_size == 0)
{
return false;
@ -387,10 +403,6 @@ static bool queue_init(struct _queue * self, uint32_t obj_size)
// base
self->_destory = queue_destory;
// iter
self->_iter.hasnext = queue_iter_hasnext;
self->_iter.next = queue_iter_next;
// -------------------- public --------------------
// kernel
self->push = queue_push;
@ -417,8 +429,6 @@ static bool queue_init(struct _queue * self, uint32_t obj_size)
static bool queue_init2(struct _queue * self, uint32_t obj_size, uint32_t capacity)
{
assert(self != NULL);
assert(obj_size > 0);
assert(capacity > 0);
if(self == NULL || obj_size == 0 || capacity == 0)
{
return false;
@ -471,7 +481,7 @@ static bool queue_init2(struct _queue * self, uint32_t obj_size, uint32_t capaci
self->clear = queue2_clear;
// iter
self->iter = queue_iter;
self->iter = queue2_iter;
// -------------------- debug --------------------
self->print = queue2_print;

View File

@ -254,63 +254,64 @@ static void stack2_print(struct _stack* self)
}
}
/**
* @brief iterator next
* from top to bottom
*
* @param iter
* @return const void*
* the value of return is const, so you can't modify it.
*/
const void* stack_iter_next(struct _iterator* iter)
{
assert(iter != NULL);
assert(iter->parent != NULL);
stack_t self = (stack_t)iter->_parent;
void *obj = NULL;
if(self->_head->obj == NULL)
{
// base on linklist
struct _stack_node* node = (struct _stack_node *)self->_iter._cur_node;
if(node != NULL)
{
obj = node->obj;
self->_iter._cur_node = node->next;
}
}
else
{
// base on array
uint32_t index = self->size(self) - 1 - self->_iter._cur;
obj = self->_head->obj + self->_obj_size * index;
}
self->_iter._cur += 1;
return obj;
}
bool stack_iter_hasnext(struct _iterator* iter)
{
assert(iter != NULL);
assert(iter->parent != NULL);
assert(iter->_container != NULL);
stack_t self = (stack_t)iter->_parent;
if(self->_iter._cur < self->size(self))
stack_t self = (stack_t)iter->_container;
if(iter->_index < self->size(self))
{
return true;
}
return false;
}
/**
* @brief iter next
* from top to bottom
*/
const void* stack_iter_next(struct _iterator* iter)
{
assert(iter != NULL);
assert(iter->_container != NULL);
stack_t self = (stack_t)iter->_container;
void *obj = NULL;
if(self->_head->obj == NULL)
{
// base on linklist
struct _stack_node* node = (struct _stack_node *)iter->_node;
if(node != NULL)
{
obj = node->obj;
iter->_node = node->next;
}
}
else
{
// base on array
uint32_t index = self->size(self) - 1 - iter->_index;
obj = self->_head->obj + self->_obj_size * index;
}
iter->_index += 1;
return obj;
}
iterator_t stack_iter(struct _stack* self)
{
assert(self != NULL);
self->_iter._parent = self;
self->_iter._cur = 0;
self->_iter._cur_node = self->_head->next;
return &self->_iter;
iterator_t iter = &self->_iter;
iter->_container = self;
iter->_index = 0;
iter->_node = self->_head->next;
iter->hasnext = stack_iter_hasnext;
iter->next = stack_iter_next;
return iter;
}
static bool stack_init(struct _stack* self, uint32_t obj_size)
@ -336,9 +337,6 @@ static bool stack_init(struct _stack* self, uint32_t obj_size)
self->_head->obj = NULL;
self->_head->next = NULL;
self->_iter.next = stack_iter_next;
self->_iter.hasnext = stack_iter_hasnext;
self->_destory = stack_destory;
// ---------- public ----------

File diff suppressed because it is too large Load Diff

23
src/unicstl_internal.c Normal file
View File

@ -0,0 +1,23 @@
/**
* @file unicstl_internal.c
* @author wenjf (Orig5826@163.com)
* @brief
* @version 0.1
* @date 2025-04-29
*
* @copyright Copyright (c) 2025
*
*/
#include "common.h"
int default_compare(void* obj1, void* obj2)
{
printf("compare is not implemented!\n");
assert(0);
}
void default_print_obj(void* obj)
{
printf("print_obj is not implemented!\n");
assert(0);
}

View File

@ -113,6 +113,7 @@ static void test_deque_num(void)
}
}
#if 0
for (i = 0; i < len; i++)
{
TEST_ASSERT_TRUE(deque->push_front(deque, &data[i]));
@ -130,6 +131,7 @@ static void test_deque_num(void)
{
TEST_ASSERT_TRUE(deque->get(deque, i, &temp));
}
#endif
deque_free(&deque);
TEST_ASSERT_NULL(deque);
@ -254,10 +256,12 @@ static void test_deque_struct(void)
TEST_ASSERT_TRUE(deque->push_front(deque, &data[i]));
}
#if 0
for (i = 0; i < len; i++)
{
TEST_ASSERT_TRUE(deque->get(deque, i, &temp));
}
#endif
deque_free(&deque);
TEST_ASSERT_NULL(deque);
@ -267,7 +271,7 @@ static void test_deque_struct(void)
static void test_deque_iter(void)
{
uint32_t i = 0;
int data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int data[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int temp = 0;
uint32_t len = sizeof(data) / sizeof(data[0]);
@ -288,26 +292,33 @@ static void test_deque_iter(void)
TEST_ASSERT_EQUAL_INT(i + 1, deque->size(deque));
}
iterator_t iter = deque->iter(deque);
iterator_t iter = deque->iter(deque, DEQUE_FORWARD);
i = 0;
while(iter->hasnext(iter))
{
temp = *(int *)iter->next(iter);
// printf("%d ", temp);
TEST_ASSERT_EQUAL_INT(data[i], temp);
i++;
}
iter = deque->iter(deque);
iter = deque->iter(deque, DEQUE_FORWARD);
i = 0;
while(iter->hasnext(iter))
{
temp = *(int *)iter->next(iter);
// printf("%d ", temp);
TEST_ASSERT_EQUAL_INT(data[i], temp);
i++;
}
iter = deque->iter(deque, DEQUE_REVERSE);
i = len - 1;
while(iter->hasnext(iter))
{
temp = *(int *)iter->next(iter);
TEST_ASSERT_EQUAL_INT(data[i], temp);
i--;
}
deque_free(&deque);
TEST_ASSERT_NULL(deque);
}

View File

@ -149,7 +149,7 @@ void test_graph_iter(void)
TEST_ASSERT_TRUE(graph->add_edge(graph, &data[7], &data[6], 87));
TEST_ASSERT_TRUE(graph->add_edge(graph, &data[8], &data[2], 92));
TEST_ASSERT_FALSE(graph->add_edge(graph, &temp, &data[1], 0));
graph->print(graph);
// graph->print(graph);
iterator_t iter_vertex = NULL;
@ -158,18 +158,18 @@ void test_graph_iter(void)
while(iter_vertex->hasnext(iter_vertex))
{
temp = *(int *)iter_vertex->next(iter_vertex);
graph->print_obj(&temp);
//graph->print_obj(&temp);
}
printf("\n");
//printf("\n");
iter_vertex = graph->iter(graph, GRAPH_DFS, &data[0]);
TEST_ASSERT_NOT_NULL(iter_vertex);
while(iter_vertex->hasnext(iter_vertex))
{
temp = *(int *)iter_vertex->next(iter_vertex);
graph->print_obj(&temp);
//graph->print_obj(&temp);
}
printf("\n");
//printf("\n");
graph_free(&graph);
TEST_ASSERT_NULL(graph);

View File

@ -26,7 +26,6 @@ static void test_list_new(void)
TEST_ASSERT_NULL(list_new2(sizeof(int), 0));
}
static void test_list_append(void)
{
int temp = 0;
@ -39,7 +38,7 @@ static void test_list_append(void)
// ------------------------------
list = list_new2(sizeof(int), len);
TEST_ASSERT_TRUE(list->empty(list));
for(i = 0; i < len; i++)
for (i = 0; i < len; i++)
{
TEST_ASSERT_TRUE(list->append(list, &data[i]));
TEST_ASSERT_EQUAL_INT(i + 1, list->size(list));
@ -54,7 +53,7 @@ static void test_list_append(void)
// ------------------------------
// if capacity is less than data len
list = list_new2(sizeof(int), len - 2);
for(i = 0; i < len; i++)
for (i = 0; i < len; i++)
{
TEST_ASSERT_TRUE(list->append(list, &data[i]));
TEST_ASSERT_EQUAL_INT(i + 1, list->size(list));
@ -62,7 +61,6 @@ static void test_list_append(void)
list_free(&list);
}
static void test_list_pop(void)
{
int temp = 0;
@ -74,19 +72,91 @@ static void test_list_pop(void)
// ------------------------------
list = list_new2(sizeof(int), len);
for(i = 0; i < len; i++)
for (i = 0; i < len; i++)
{
list->append(list, &data[i]);
}
for (i = 0; i < len; i++)
{
TEST_ASSERT_TRUE(list->pop(list, 0, &temp));
TEST_ASSERT_TRUE(list->pop(list, &temp));
}
TEST_ASSERT_TRUE(list->empty(list));
// TEST_ASSERT_FALSE(list->pop(list, 1, &temp));
TEST_ASSERT_FALSE(list->pop(list, &temp));
list_free(&list);
}
static void test_list_insert(void)
{
int temp = 0;
int data[] = { 1,2,3,4,5,6,7,8,9,10 };
uint32_t len = sizeof(data) / sizeof(data[0]);
uint32_t i = 0;
list_t list = NULL;
// ------------------------------
list = list_new2(sizeof(int), len);
list->print_obj = print_num;
TEST_ASSERT_TRUE(list->empty(list));
for (i = 0; i < len; i++)
{
TEST_ASSERT_TRUE(list->insert(list, i, &data[i]));
TEST_ASSERT_EQUAL_INT(i + 1, list->size(list));
TEST_ASSERT_TRUE(list->get(list, i, &temp));
TEST_ASSERT_EQUAL_INT(data[i], temp);
// list->print(list);
// printf("\n");
}
list->clear(list);
TEST_ASSERT_TRUE(list->empty(list));
for (i = 0; i < len; i++)
{
TEST_ASSERT_TRUE(list->insert(list, 0, &data[i]));
TEST_ASSERT_EQUAL_INT(i + 1, list->size(list));
TEST_ASSERT_TRUE(list->get(list, 0, &temp));
TEST_ASSERT_EQUAL_INT(data[i], temp);
// list->print(list);
// printf("\n");
}
TEST_ASSERT_FALSE(list->empty(list));
list_free(&list);
}
static void test_list_delete(void)
{
int temp = 0;
int data[] = { 1,2,3,4,5,6,7,8,9,10 };
uint32_t len = sizeof(data) / sizeof(data[0]);
uint32_t i = 0;
list_t list = NULL;
// ------------------------------
list = list_new2(sizeof(int), len);
for (i = 0; i < len; i++)
{
list->append(list, &data[i]);
}
TEST_ASSERT_TRUE(list->delete(list, len - 1, &temp));
TEST_ASSERT_EQUAL_INT(data[len - 1], temp);
for (i = 0; i < len - 1; i++)
{
TEST_ASSERT_TRUE(list->delete(list, 0, &temp));
TEST_ASSERT_EQUAL_INT(data[i], temp);
}
TEST_ASSERT_TRUE(list->empty(list));
TEST_ASSERT_FALSE(list->pop(list, &temp));
list_free(&list);
}
static void test_list_clear(void)
{
@ -100,7 +170,7 @@ static void test_list_clear(void)
// ------------------------------
list = list_new2(sizeof(int), len);
TEST_ASSERT_TRUE(list->clear(list));
for(i = 0; i < len; i++)
for (i = 0; i < len; i++)
{
list->append(list, &data[i]);
}
@ -129,9 +199,9 @@ static void test_list_num(void)
{
TEST_ASSERT_TRUE(list->append(list, &data[i]));
}
TEST_ASSERT_TRUE(list->pop(list, 9, NULL));
TEST_ASSERT_TRUE(list->pop(list, 0, NULL));
TEST_ASSERT_TRUE(list->pop(list, 4, NULL));
TEST_ASSERT_TRUE(list->delete(list, 9, NULL));
TEST_ASSERT_TRUE(list->delete(list, 0, NULL));
TEST_ASSERT_TRUE(list->delete(list, 4, NULL));
TEST_ASSERT_TRUE(list->clear(list));
for (i = 0; i < len; i++)
@ -182,7 +252,7 @@ static void test_list_num(void)
for (i = 0; i < len + 1; i++)
{
TEST_ASSERT_TRUE(list->pop(list, 0, &temp));
TEST_ASSERT_TRUE(list->pop(list, &temp));
if (list->empty(list))
{
@ -202,7 +272,7 @@ static void test_list_struct(void)
"zhou", 1005, "wu", 1006, "zheng", 1007, "wang", 1008,
"feng", 1009, "cheng",1010,
};
struct _student temp = {0};
struct _student temp = { 0 };
int index = 0;
int len = sizeof(data) / sizeof(data[0]);
@ -213,9 +283,9 @@ static void test_list_struct(void)
{
TEST_ASSERT_TRUE(list->append(list, &data[i]));
}
TEST_ASSERT_TRUE(list->pop(list, 9, NULL));
TEST_ASSERT_TRUE(list->pop(list, 0, NULL));
TEST_ASSERT_TRUE(list->pop(list, 4, NULL));
TEST_ASSERT_TRUE(list->delete(list, 9, NULL));
TEST_ASSERT_TRUE(list->delete(list, 0, NULL));
TEST_ASSERT_TRUE(list->delete(list, 4, NULL));
TEST_ASSERT_TRUE(list->clear(list));
for (i = 0; i < len; i++)
@ -267,12 +337,12 @@ static void test_list_struct(void)
TEST_ASSERT_TRUE(list->set(list, index, &temp));
index = -10;
temp = (struct _student){"robot", 97};
temp = (struct _student){ "robot", 97 };
TEST_ASSERT_TRUE(list->set(list, index, &temp));
for (i = 0; i < len + 1; i++)
{
TEST_ASSERT_TRUE(list->pop(list, 0, &temp));
TEST_ASSERT_TRUE(list->pop(list, &temp));
if (list->empty(list))
{
@ -284,51 +354,6 @@ static void test_list_struct(void)
TEST_ASSERT_NULL(list);
}
#if 0
static void test_list_iter(void)
{
int temp = 0;
int data[32] = { 1,2,3,4,5,6,7,8,9,10 };
// uint32_t len = sizeof(data) / sizeof(data[0]);
uint32_t len = 10;
uint32_t i = 0;
int buff[32];
int count = 0;
list_t list = NULL;
// ------------------------------
list = list_new2(sizeof(int), len);
TEST_ASSERT_TRUE(list->clear(list));
for(i = 0; i < len; i++)
{
list->append(list, &data[i]);
}
int * iter = NULL;
iter = list->begin(list);
for(count = 0, i = 0; i < len + 12; i++)
{
if(i < len)
{
TEST_ASSERT_EQUAL_INT(data[i % len], *iter);
}
iter = list->next(list);
}
for(count=0, iter = list->begin(list); iter != list->end(list); iter = list->next(list))
{
buff[count++] = *iter;
}
TEST_ASSERT_EQUAL_INT_ARRAY(data, buff, count);
TEST_ASSERT_FALSE(list->empty(list));
TEST_ASSERT_TRUE(list->clear(list));
TEST_ASSERT_TRUE(list->empty(list));
TEST_ASSERT_TRUE(list->clear(list));
list_free(&list);
}
#else
void test_list_iter(void)
{
int temp = 0;
@ -343,7 +368,7 @@ void test_list_iter(void)
TEST_ASSERT_TRUE(list->empty(list));
list->print_obj = print_num;
for(i = 0; i < len; i++)
for (i = 0; i < len; i++)
{
TEST_ASSERT_TRUE(list->append(list, &data[i]));
TEST_ASSERT_EQUAL_INT(i + 1, list->size(list));
@ -357,7 +382,7 @@ void test_list_iter(void)
iterator_t iter = list->iter(list);
int iter_data = 0;
int idx = 0;
while(iter->hasnext(iter))
while (iter->hasnext(iter))
{
iter_data = *(int*)iter->next(iter);
// printf("%d ", iter_data);
@ -366,19 +391,389 @@ void test_list_iter(void)
}
list_free(&list);
}
#endif
static void test_list_index(void)
{
int temp = 0;
int data[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
uint32_t len = sizeof(data) / sizeof(data[0]);
uint32_t i = 0;
list_t list = NULL;
// ------------------------------
list = list_new2(sizeof(int), len);
list->compare = compare_num;
for (i = 0; i < len; i++)
{
TEST_ASSERT_TRUE(list->append(list, &data[i]));
}
TEST_ASSERT_EQUAL_INT(0, list->index(list, &data[0]));
TEST_ASSERT_EQUAL_INT(5, list->index(list, &data[5]));
TEST_ASSERT_EQUAL_INT(9, list->index(list, &data[9]));
temp = 11;
TEST_ASSERT_EQUAL_INT(-1, list->index(list, &temp));
list_free(&list);
}
static void test_list_slice_empty(void)
{
int temp = 0;
int data[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
uint32_t len = sizeof(data) / sizeof(data[0]);
uint32_t i = 0;
list_t list = NULL;
list_t list2 = NULL;
// ------------------------------
list = list_new2(sizeof(int), len);
list->compare = compare_num;
list->print_obj = print_num;
for (i = 0; i < len; i++)
{
TEST_ASSERT_TRUE(list->append(list, &data[i]));
}
// -------------------- NULL --------------------
// python: list[0:] -> []
list2 = list->slice(list, 1, 5, 0); // if step == 0
TEST_ASSERT_NULL(list2);
// list_free(&list2);
// -------------------- empty --------------------
list2 = list->slice(list, 0, 0, 1); // if start == end
TEST_ASSERT_NOT_NULL(list2);
TEST_ASSERT_TRUE(list2->empty(list2));
list_free(&list2);
list2 = list->slice(list, len, LIST_UNLIMITED, 1); // if start == end
TEST_ASSERT_NOT_NULL(list2);
TEST_ASSERT_TRUE(list2->empty(list2));
list_free(&list2);
list2 = list->slice(list, 1, 5, -1); // if start < end && step < 0
TEST_ASSERT_NOT_NULL(list2);
TEST_ASSERT_TRUE(list2->empty(list2));
list_free(&list2);
list2 = list->slice(list, 5, 1, 1); // if start > end && step > 0
TEST_ASSERT_NOT_NULL(list2);
TEST_ASSERT_TRUE(list2->empty(list2));
list_free(&list2);
list2 = list->slice(list, -1, -5, 1); // if start < end && step < 0
TEST_ASSERT_NOT_NULL(list2);
TEST_ASSERT_TRUE(list2->empty(list2));
list_free(&list2);
list2 = list->slice(list, -5, -1, -1); // if start > end && step > 0
TEST_ASSERT_NOT_NULL(list2);
TEST_ASSERT_TRUE(list2->empty(list2));
list_free(&list2);
// -------------------- empty --------------------
list2 = list->slice(list, len, len + 1, 1); // if start > start_max
TEST_ASSERT_NOT_NULL(list2);
TEST_ASSERT_TRUE(list2->empty(list2));
list_free(&list2);
list2 = list->slice(list, -len - 1, -len, 1); // if end < end_min
TEST_ASSERT_NOT_NULL(list2);
TEST_ASSERT_TRUE(list2->empty(list2));
list_free(&list2);
list_free(&list);
}
static void test_list_slice_positive(void)
{
int temp = 0;
int data[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
uint32_t len = sizeof(data) / sizeof(data[0]);
uint32_t i = 0;
list_t list = NULL;
list_t list2 = NULL;
// ------------------------------
list = list_new2(sizeof(int), len);
list->compare = compare_num;
list->print_obj = print_num;
for (i = 0; i < len; i++)
{
TEST_ASSERT_TRUE(list->append(list, &data[i]));
}
// -------------------- elements --------------------
// python: list[0:]
list2 = list->slice(list, 0, len, 1);
TEST_ASSERT_NOT_NULL(list2);
//list2->print(list2); printf("\n");
TEST_ASSERT_EQUAL_INT(len, list2->size(list2));
for(i = 0; i < list2->size(list2); i++)
{
TEST_ASSERT_TRUE(list2->get(list2, i, &temp));
TEST_ASSERT_EQUAL_INT(data[i], temp);
}
list_free(&list2);
// python: list[0:11] if len(list) == 10
list2 = list->slice(list, 0, len + 1, 1);
TEST_ASSERT_NOT_NULL(list2);
// list2->print(list2); printf("\n");
TEST_ASSERT_EQUAL_INT(len, list2->size(list2));
for(i = 0; i < list2->size(list2); i++)
{
TEST_ASSERT_TRUE(list2->get(list2, i, &temp));
TEST_ASSERT_EQUAL_INT(data[i], temp);
}
list_free(&list2);
// python: list[-6:8] or list[-6:-2] or list[4:8]
list2 = list->slice(list, 4, 8, 1);
TEST_ASSERT_NOT_NULL(list2);
//list2->print(list2); printf("\n");
TEST_ASSERT_EQUAL_INT(4, list2->size(list2));
for(i = 0; i < list2->size(list2); i++)
{
TEST_ASSERT_TRUE(list2->get(list2, i, &temp));
TEST_ASSERT_EQUAL_INT(data[len - 6 + i], temp);
}
list_free(&list2);
// python: list[4:0:-1]
list2 = list->slice(list, 4, 0, -1);
TEST_ASSERT_NOT_NULL(list2);
// list2->print(list2); printf("\n");
TEST_ASSERT_EQUAL_INT(4, list2->size(list2));
for(i = 0; i < list2->size(list2); i++)
{
TEST_ASSERT_TRUE(list2->get(list2, i, &temp));
TEST_ASSERT_EQUAL_INT(data[list2->size(list2) - i], temp);
}
list_free(&list2);
// python: list[::2]
list2 = list->slice(list, 0, len, 2);
TEST_ASSERT_NOT_NULL(list2);
// list2->print(list2); printf("\n");
TEST_ASSERT_EQUAL_INT(5, list2->size(list2));
for(i = 0; i < list2->size(list2); i++)
{
TEST_ASSERT_TRUE(list2->get(list2, i, &temp));
TEST_ASSERT_EQUAL_INT(data[i * 2], temp);
}
list_free(&list2);
list_free(&list);
}
static void test_list_slice_negative(void)
{
int temp = 0;
int data[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
uint32_t len = sizeof(data) / sizeof(data[0]);
uint32_t i = 0;
list_t list = NULL;
list_t list2 = NULL;
// ------------------------------
list = list_new2(sizeof(int), len);
list->compare = compare_num;
list->print_obj = print_num;
for (i = 0; i < len; i++)
{
TEST_ASSERT_TRUE(list->append(list, &data[i]));
}
// -------------------- elements --------------------
// python: list[:-1]
list2 = list->slice(list, 0, -1, 1);
TEST_ASSERT_NOT_NULL(list2);
//list2->print(list2); printf("\n");
TEST_ASSERT_EQUAL_INT(len - 1, list2->size(list2));
for(i = 0; i < list2->size(list2); i++)
{
TEST_ASSERT_TRUE(list2->get(list2, i, &temp));
TEST_ASSERT_EQUAL_INT(data[i], temp);
}
list_free(&list2);
// python: list[:-1]
list2 = list->slice(list, -1, len, 1);
TEST_ASSERT_NOT_NULL(list2);
//list2->print(list2); printf("\n");
TEST_ASSERT_EQUAL_INT(1, list2->size(list2));
TEST_ASSERT_TRUE(list2->get(list2, 0, &temp));
TEST_ASSERT_EQUAL_INT(data[len - 1], temp);
list_free(&list2);
// python: list[-6:8] or list[-6:-2]
// list2 = list->slice(list, -6, 8, 1); // It can be executed, but it's not intuitive
list2 = list->slice(list, -6, -2, 1);
TEST_ASSERT_NOT_NULL(list2);
//list2->print(list2); printf("\n");
TEST_ASSERT_EQUAL_INT(4, list2->size(list2));
for(i = 0; i < list2->size(list2); i++)
{
TEST_ASSERT_TRUE(list2->get(list2, i, &temp));
TEST_ASSERT_EQUAL_INT(data[len - 6 + i], temp);
}
list_free(&list2);
// -------------------- step == 2 --------------------
// python: list[::-2]
list2 = list->slice(list, len-1, 0, -2);
TEST_ASSERT_NOT_NULL(list2);
// list2->print(list2); printf("\n");
TEST_ASSERT_EQUAL_INT(5, list2->size(list2));
for(i = 0; i < list2->size(list2); i++)
{
TEST_ASSERT_TRUE(list2->get(list2, i, &temp));
TEST_ASSERT_EQUAL_INT(data[9 - i * 2], temp);
}
list_free(&list2);
// -------------------- start_limit --------------------
// list[-len-1:-1]
list2 = list->slice(list, -len-1, -1, 1);
TEST_ASSERT_NOT_NULL(list2);
// list2->print(list2); printf("\n");
TEST_ASSERT_EQUAL_INT(len - 1, list2->size(list2));
for(i = 0; i < list2->size(list2); i++)
{
TEST_ASSERT_TRUE(list2->get(list2, i, &temp));
TEST_ASSERT_EQUAL_INT(data[i], temp);
}
list_free(&list2);
list_free(&list);
}
static void test_list_slice_unlimited(void)
{
int temp = 0;
int data[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
uint32_t len = sizeof(data) / sizeof(data[0]);
uint32_t i = 0;
list_t list = NULL;
list_t list2 = NULL;
// ------------------------------
list = list_new2(sizeof(int), len);
list->compare = compare_num;
list->print_obj = print_num;
for (i = 0; i < len; i++)
{
TEST_ASSERT_TRUE(list->append(list, &data[i]));
}
// -------------------- umlimited --------------------
// python: list[0:]
list2 = list->slice(list, 0, LIST_UNLIMITED, 1);
TEST_ASSERT_NOT_NULL(list2);
//list2->print(list2); printf("\n");
TEST_ASSERT_EQUAL_INT(len, list2->size(list2));
for(i = 0; i < list2->size(list2); i++)
{
TEST_ASSERT_TRUE(list2->get(list2, i, &temp));
TEST_ASSERT_EQUAL_INT(data[i], temp);
}
list_free(&list2);
// python: list[4::-1]
list2 = list->slice(list, 4, LIST_UNLIMITED, -1);
TEST_ASSERT_NOT_NULL(list2);
//list2->print(list2); printf("\n");
TEST_ASSERT_EQUAL_INT(5, list2->size(list2));
for(i = 0; i < list2->size(list2); i++)
{
TEST_ASSERT_TRUE(list2->get(list2, i, &temp));
TEST_ASSERT_EQUAL_INT(data[list2->size(list2) - 1 - i], temp);
}
list_free(&list2);
list2 = list->slice(list, LIST_UNLIMITED, LIST_UNLIMITED, 1);
TEST_ASSERT_NOT_NULL(list2);
//list2->print(list2); printf("\n");
TEST_ASSERT_EQUAL_INT(len, list2->size(list2));
for(i = 0; i < list2->size(list2); i++)
{
TEST_ASSERT_TRUE(list2->get(list2, i, &temp));
TEST_ASSERT_EQUAL_INT(data[i], temp);
}
list_free(&list2);
list2 = list->slice(list, LIST_UNLIMITED, LIST_UNLIMITED, -1);
TEST_ASSERT_NOT_NULL(list2);
//list2->print(list2); printf("\n");
TEST_ASSERT_EQUAL_INT(len, list2->size(list2));
for(i = 0; i < list2->size(list2); i++)
{
TEST_ASSERT_TRUE(list2->get(list2, i, &temp));
TEST_ASSERT_EQUAL_INT(data[list2->size(list2) - 1 - i], temp);
}
list_free(&list2);
// -------------------- step == 2 --------------------
list2 = list->slice(list, LIST_UNLIMITED, LIST_UNLIMITED, 2);
TEST_ASSERT_NOT_NULL(list2);
//list2->print(list2); printf("\n");
TEST_ASSERT_EQUAL_INT(5, list2->size(list2));
for(i = 0; i < list2->size(list2); i++)
{
TEST_ASSERT_TRUE(list2->get(list2, i, &temp));
TEST_ASSERT_EQUAL_INT(data[i * 2], temp);
}
list_free(&list2);
list2 = list->slice(list, LIST_UNLIMITED, LIST_UNLIMITED, -2);
TEST_ASSERT_NOT_NULL(list2);
//list2->print(list2); printf("\n");
TEST_ASSERT_EQUAL_INT(5, list2->size(list2));
for(i = 0; i < list2->size(list2); i++)
{
TEST_ASSERT_TRUE(list2->get(list2, i, &temp));
TEST_ASSERT_EQUAL_INT(data[9 - i*2], temp);
}
list_free(&list2);
list_free(&list);
}
void test_list(void)
{
UnitySetTestFile(__FILE__);
RUN_TEST(test_list_new);
RUN_TEST(test_list_append);
RUN_TEST(test_list_pop);
RUN_TEST(test_list_insert);
RUN_TEST(test_list_delete);
RUN_TEST(test_list_clear);
RUN_TEST(test_list_num);
RUN_TEST(test_list_struct);
RUN_TEST(test_list_iter);
RUN_TEST(test_list_index);
RUN_TEST(test_list_slice_empty);
RUN_TEST(test_list_slice_positive);
RUN_TEST(test_list_slice_negative);
RUN_TEST(test_list_slice_unlimited);
}

View File

@ -67,7 +67,7 @@ static const int expected_int_array_orderpre_delete[15][15] = {
{ 13, },
};
static const enum _order order[8] = {
static const enum _tree_order order[8] = {
ORDER_PRE, ORDER_IN, ORDER_POST, ORDER_BREADTH,
ORDER_PRE_R, ORDER_IN_R, ORDER_POST_R, ORDER_BREADTH_R
};
@ -335,10 +335,6 @@ static void test_rbtree_delete(void)
int temp = 0;
int count = 0;
iterator_t iter = NULL;
enum _order order[8] = {
ORDER_PRE, ORDER_IN, ORDER_POST, ORDER_BREADTH,
ORDER_PRE_R, ORDER_IN_R, ORDER_POST_R, ORDER_BREADTH_R
};
tree_t tree = tree_rb_new(sizeof(int));
TEST_ASSERT_NOT_NULL(tree);