mirror of
https://gitee.com/apaki/unicstl.git
synced 2025-07-06 00:46:52 +08:00
Compare commits
No commits in common. "32f2605656883c1a1c7810f0f644d0e2df0cf374" and "9e270b7425300806192eeac58adb277af7792846" have entirely different histories.
32f2605656
...
9e270b7425
5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
@ -26,9 +26,6 @@
|
|||||||
"graph.h": "c",
|
"graph.h": "c",
|
||||||
"unicstl_config.h": "c",
|
"unicstl_config.h": "c",
|
||||||
"iter.h": "c",
|
"iter.h": "c",
|
||||||
"iterator.h": "c",
|
"iterator.h": "c"
|
||||||
"assert.h": "c",
|
|
||||||
"limits.h": "c",
|
|
||||||
"cstdint": "c"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
102
README.md
102
README.md
@ -1,19 +1,13 @@
|
|||||||
# unicstl
|
# unicstl
|
||||||
|
|
||||||
## 简介
|
## 简介
|
||||||
基于C语言实现的通用C库,包含常用数据结构和算法。
|
全称: Universal C standard library
|
||||||
|
|
||||||
**全称:** Universal C standard library
|
基于C语言实现的通用C库。包含常用数据结构和算法
|
||||||
|
|
||||||
**作者:** 温建峰
|
> 标准:--std=c99
|
||||||
|
|
||||||
**主页:** [博客](https://blog.wenjianfeng.top)
|
[数据结构详细说明](https://blog.wenjianfeng.top)
|
||||||
|
|
||||||
**邮箱:**[orig5826@163.com](mailto:orig5826@163.com)
|
|
||||||
|
|
||||||
## 编译环境
|
|
||||||
- 编译器:gcc 13.2.0
|
|
||||||
- 标准:--std=c99
|
|
||||||
|
|
||||||
## 数据结构
|
## 数据结构
|
||||||
|数据结构 | 原理 |说明 |
|
|数据结构 | 原理 |说明 |
|
||||||
@ -33,80 +27,12 @@
|
|||||||
| tree_rb_new | 二叉搜索树 | 红黑树 |
|
| tree_rb_new | 二叉搜索树 | 红黑树 |
|
||||||
| **heap** | |**堆** |
|
| **heap** | |**堆** |
|
||||||
| heap_new2 | 数组 | 最大堆/最小堆 |
|
| 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); // 获取元素
|
|
||||||
```
|
|
||||||
|
|
||||||
## 特点
|
## 特点
|
||||||
| 原理 | 优势 | 弊端 |
|
| 原理 | 说明 |
|
||||||
| --- | --- |--- |
|
| --- | --- |
|
||||||
| 链表 | 插入删除效率高 | 有额外指针开销 |
|
| 链表 | 有额外指针开销 |
|
||||||
| 动态数组 | 随机访问效率高 | 扩容时数据搬移代价较大 |
|
| 动态数组 | 扩容时数据搬移代价较大 |
|
||||||
| --- | --- | --- |
|
|
||||||
| 单链表 | 适用内存受限场景 | 逆向不便 |
|
|
||||||
| 双向链表 | 频繁双向遍历的场景(如光标移动) | 空间开销大 |
|
|
||||||
|
|
||||||
|
|
||||||
## 性能比较
|
## 性能比较
|
||||||
@ -165,18 +91,6 @@ 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)
|
### Unicstl 0.0.01 (2025-04-24)
|
||||||
- new features
|
- new features
|
||||||
- add stack
|
- add stack
|
||||||
|
@ -140,7 +140,6 @@ static void demo_deque_num(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
printf("----- push_front -----\n");
|
printf("----- push_front -----\n");
|
||||||
for (i = 0; i < len; i++)
|
for (i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
@ -174,7 +173,6 @@ static void demo_deque_num(void)
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
deque_free(&deque);
|
deque_free(&deque);
|
||||||
}
|
}
|
||||||
@ -336,6 +334,7 @@ static void demo_deque_struct(void)
|
|||||||
printf("----- print -----\n");
|
printf("----- print -----\n");
|
||||||
deque->print(deque);
|
deque->print(deque);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
printf("----- get -----\n");
|
printf("----- get -----\n");
|
||||||
for (i = 0; i < len; i++)
|
for (i = 0; i < len; i++)
|
||||||
@ -347,7 +346,6 @@ static void demo_deque_struct(void)
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
deque_free(&deque);
|
deque_free(&deque);
|
||||||
}
|
}
|
||||||
|
@ -32,15 +32,15 @@ static void demo_list_num(void)
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
printf("----- pop -----\n");
|
printf("----- pop -----\n");
|
||||||
list->delete(list, 9, NULL);
|
list->pop(list, 9, NULL);
|
||||||
list->print(list);
|
list->print(list);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
list->delete(list, 0, NULL);
|
list->pop(list, 0, NULL);
|
||||||
list->print(list);
|
list->print(list);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
list->delete(list, 4, NULL);
|
list->pop(list, 4, NULL);
|
||||||
list->print(list);
|
list->print(list);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
@ -129,7 +129,7 @@ static void demo_list_num(void)
|
|||||||
printf("----- pop -----\n");
|
printf("----- pop -----\n");
|
||||||
for (i = 0; i < len + 1; i++)
|
for (i = 0; i < len + 1; i++)
|
||||||
{
|
{
|
||||||
list->pop(list, &temp);
|
list->pop(list, 0, &temp);
|
||||||
|
|
||||||
if (list->empty(list))
|
if (list->empty(list))
|
||||||
{
|
{
|
||||||
@ -167,15 +167,15 @@ static void demo_list_struct(void)
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
printf("----- pop -----\n");
|
printf("----- pop -----\n");
|
||||||
list->delete(list, 9, NULL);
|
list->pop(list, 9, NULL);
|
||||||
list->print(list);
|
list->print(list);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
list->delete(list, 0, NULL);
|
list->pop(list, 0, NULL);
|
||||||
list->print(list);
|
list->print(list);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
list->delete(list, 4, NULL);
|
list->pop(list, 4, NULL);
|
||||||
list->print(list);
|
list->print(list);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
@ -286,7 +286,7 @@ static void demo_list_struct(void)
|
|||||||
printf("----- pop -----\n");
|
printf("----- pop -----\n");
|
||||||
for (i = 0; i < len + 1; i++)
|
for (i = 0; i < len + 1; i++)
|
||||||
{
|
{
|
||||||
list->pop(list, &temp);
|
list->pop(list, 0, &temp);
|
||||||
|
|
||||||
if (list->empty(list))
|
if (list->empty(list))
|
||||||
{
|
{
|
||||||
|
@ -39,9 +39,4 @@
|
|||||||
*/
|
*/
|
||||||
typedef int (*compare_fun_t)(void* obj, void* obj2);
|
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_
|
#endif // _COMMON_H_
|
||||||
|
@ -13,12 +13,6 @@
|
|||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
enum _deque_order
|
|
||||||
{
|
|
||||||
DEQUE_FORWARD,
|
|
||||||
DEQUE_REVERSE,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _deque_node
|
struct _deque_node
|
||||||
{
|
{
|
||||||
void* obj;
|
void* obj;
|
||||||
@ -49,14 +43,28 @@ struct _deque
|
|||||||
bool (*pop_front)(struct _deque* self, void* obj);
|
bool (*pop_front)(struct _deque* self, void* obj);
|
||||||
bool (*back)(struct _deque* self, void* obj);
|
bool (*back)(struct _deque* self, void* obj);
|
||||||
bool (*front)(struct _deque* self, void* obj);
|
bool (*front)(struct _deque* self, void* obj);
|
||||||
|
bool (*empty)(struct _deque* self);
|
||||||
|
|
||||||
// base
|
// base
|
||||||
uint32_t(*size)(struct _deque* self);
|
uint32_t(*size)(struct _deque* self);
|
||||||
bool (*clear)(struct _deque* self);
|
bool (*clear)(struct _deque* self);
|
||||||
bool (*empty)(struct _deque* self);
|
|
||||||
|
|
||||||
// iter
|
// iter
|
||||||
iterator_t (*iter)(struct _deque* self, enum _deque_order order);
|
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);
|
||||||
|
|
||||||
// -------------------- debug --------------------
|
// -------------------- debug --------------------
|
||||||
void (*print)(struct _deque* self);
|
void (*print)(struct _deque* self);
|
||||||
|
@ -78,11 +78,12 @@ struct _graph
|
|||||||
bool (*del_edge)(struct _graph* self, void* from, void* to);
|
bool (*del_edge)(struct _graph* self, void* from, void* to);
|
||||||
bool (*find_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
|
// base
|
||||||
uint32_t(*size)(struct _graph* self);
|
uint32_t(*size)(struct _graph* self);
|
||||||
uint32_t(*capacity)(struct _graph* self);
|
uint32_t(*capacity)(struct _graph* self);
|
||||||
bool (*empty)(struct _graph* self);
|
|
||||||
bool (*full)(struct _graph* self);
|
|
||||||
bool (*clear)(struct _graph* self);
|
bool (*clear)(struct _graph* self);
|
||||||
|
|
||||||
// iter
|
// iter
|
||||||
|
@ -36,12 +36,12 @@ struct _heap
|
|||||||
|
|
||||||
// -------------------- public --------------------
|
// -------------------- public --------------------
|
||||||
// kernel
|
// kernel
|
||||||
|
bool (*peek)(struct _heap* self, void* obj);
|
||||||
bool (*push)(struct _heap* self, void* obj);
|
bool (*push)(struct _heap* self, void* obj);
|
||||||
bool (*pop)(struct _heap* self, void* obj);
|
bool (*pop)(struct _heap* self, void* obj);
|
||||||
bool (*peek)(struct _heap* self, void* obj);
|
bool (*empty)(struct _heap* self);
|
||||||
|
|
||||||
// base
|
// base
|
||||||
bool (*empty)(struct _heap* self);
|
|
||||||
uint32_t(*size)(struct _heap* self);
|
uint32_t(*size)(struct _heap* self);
|
||||||
bool (*clear)(struct _heap* self);
|
bool (*clear)(struct _heap* self);
|
||||||
|
|
||||||
|
@ -16,11 +16,9 @@
|
|||||||
struct _iterator
|
struct _iterator
|
||||||
{
|
{
|
||||||
// ---------- private ----------
|
// ---------- private ----------
|
||||||
void* _container; // pointer to stack/queue/tree ...
|
void* _parent;
|
||||||
|
void* _cur_node;
|
||||||
void* _node; // current node
|
uint32_t _cur;
|
||||||
uint32_t _index; // current index
|
|
||||||
uint32_t _order;
|
|
||||||
|
|
||||||
// ---------- public ----------
|
// ---------- public ----------
|
||||||
bool (*hasnext)(struct _iterator* self);
|
bool (*hasnext)(struct _iterator* self);
|
||||||
|
@ -1,16 +1,12 @@
|
|||||||
/**
|
/**
|
||||||
* @file list.h
|
* @file list.h
|
||||||
* @author wenjf (Orig5826@163.com)
|
* @author wenjf (Orig5826@163.com)
|
||||||
* @brief
|
* @brief
|
||||||
*
|
|
||||||
* @details dynamic array list.
|
|
||||||
* similar to python list/ java ArrayList / C++ std::vector
|
|
||||||
*
|
|
||||||
* @version 0.1
|
* @version 0.1
|
||||||
* @date 2024-06-23
|
* @date 2024-06-23
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2024
|
* @copyright Copyright (c) 2024
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#ifndef _LIST_H_
|
#ifndef _LIST_H_
|
||||||
#define _LIST_H_
|
#define _LIST_H_
|
||||||
@ -18,12 +14,10 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "iterator.h"
|
#include "iterator.h"
|
||||||
|
|
||||||
#define LIST_UNLIMITED INT32_MAX
|
|
||||||
|
|
||||||
struct _list
|
struct _list
|
||||||
{
|
{
|
||||||
// -------------------- private --------------------
|
// -------------------- private --------------------
|
||||||
void *obj;
|
void * obj;
|
||||||
|
|
||||||
uint32_t _obj_size;
|
uint32_t _obj_size;
|
||||||
uint32_t _size;
|
uint32_t _size;
|
||||||
@ -33,47 +27,47 @@ struct _list
|
|||||||
|
|
||||||
struct _iterator _iter;
|
struct _iterator _iter;
|
||||||
|
|
||||||
void (*_destory)(struct _list *self);
|
void (*_destory)(struct _list* self);
|
||||||
|
|
||||||
// -------------------- public --------------------
|
// -------------------- public --------------------
|
||||||
// kernel
|
// kernel
|
||||||
bool (*append)(struct _list *self, void *obj);
|
bool (*append)(struct _list* self, void* obj); // Append object to the end of the list.
|
||||||
bool (*pop)(struct _list *self, void *obj);
|
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 (*insert)(struct _list *self, int index, void *obj);
|
int (*index)(struct _list* self, void* obj); // Return first index of obj. Return -1 if the obj is not present.
|
||||||
bool (*delete)(struct _list *self, int index, void *obj);
|
bool (*remove)(struct _list* self, void *obj); // Remove first occurrence of obj.
|
||||||
|
|
||||||
bool (*get)(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 (*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
|
// base
|
||||||
uint32_t (*size)(struct _list *self);
|
uint32_t(*size)(struct _list* self);
|
||||||
uint32_t (*capacity)(struct _list *self);
|
bool (*empty)(struct _list* self);
|
||||||
bool (*empty)(struct _list *self);
|
bool (*clear)(struct _list* self);
|
||||||
bool (*clear)(struct _list *self);
|
|
||||||
|
|
||||||
// iter
|
// iter
|
||||||
iterator_t (*iter)(struct _list *self);
|
iterator_t (*iter)(struct _list* self);
|
||||||
|
|
||||||
// others
|
// sort
|
||||||
struct _list* (*slice)(struct _list *self, int start, int end, int step);
|
// bool (*reverse)(struct _list* self); // Reverse *IN PLACE*.
|
||||||
// struct _list* (*copy)(struct _list *self);
|
/**
|
||||||
|
Sort the list in ascending order and return false.
|
||||||
// config
|
The sort is in-place (i.e. the list itself is modified) and stable (i.e. the
|
||||||
compare_fun_t compare; // !!! you have to implement this function
|
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));
|
||||||
|
|
||||||
// -------------------- debug --------------------
|
// -------------------- debug --------------------
|
||||||
void (*print)(struct _list *self);
|
void (*print)(struct _list* self);
|
||||||
void (*print_obj)(void *obj);
|
void (*print_obj)(void* obj);
|
||||||
};
|
};
|
||||||
typedef struct _list *list_t;
|
typedef struct _list* list_t;
|
||||||
|
|
||||||
// create and free list
|
// create and free list
|
||||||
list_t list_new2(uint32_t obj_size, uint32_t capacity);
|
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_
|
#endif // _LIST_H_
|
||||||
|
@ -43,11 +43,11 @@ struct _stack
|
|||||||
bool (*push)(struct _stack* self, void* obj);
|
bool (*push)(struct _stack* self, void* obj);
|
||||||
bool (*pop)(struct _stack* self, void* obj);
|
bool (*pop)(struct _stack* self, void* obj);
|
||||||
bool (*peek)(struct _stack* self, void* obj);
|
bool (*peek)(struct _stack* self, void* obj);
|
||||||
|
bool (*empty)(struct _stack* self);
|
||||||
|
|
||||||
// base
|
// base
|
||||||
uint32_t (*size)(struct _stack* self);
|
uint32_t (*size)(struct _stack* self);
|
||||||
uint32_t (*capacity)(struct _stack* self);
|
uint32_t (*capacity)(struct _stack* self);
|
||||||
bool (*empty)(struct _stack* self);
|
|
||||||
bool (*clear)(struct _stack* self);
|
bool (*clear)(struct _stack* self);
|
||||||
|
|
||||||
// iter
|
// iter
|
||||||
|
@ -22,17 +22,29 @@ typedef enum {
|
|||||||
RBT_BLACK,
|
RBT_BLACK,
|
||||||
}rbt_color;
|
}rbt_color;
|
||||||
|
|
||||||
// dfs and bfs traversal order
|
/**
|
||||||
enum _tree_order{
|
* @brief dfs amd bfs traversal order
|
||||||
ORDER_PRE, // pre-order
|
*
|
||||||
ORDER_IN, // in-order
|
* pre-order traversal
|
||||||
ORDER_POST, // post-order
|
* in-order traversal
|
||||||
ORDER_BREADTH, // breadth-first search [BFS]
|
* 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,
|
||||||
|
|
||||||
ORDER_PRE_R, // right-first pre-order
|
ORDER_PRE_R,
|
||||||
ORDER_IN_R, // right-first in-order
|
ORDER_IN_R,
|
||||||
ORDER_POST_R, // right-first post-order
|
ORDER_POST_R,
|
||||||
ORDER_BREADTH_R,// right-first breadth-first search [BFS]
|
ORDER_BREADTH_R,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _tree_node
|
struct _tree_node
|
||||||
@ -59,19 +71,22 @@ struct _tree
|
|||||||
uint32_t _capacity;
|
uint32_t _capacity;
|
||||||
uint32_t _ratio;
|
uint32_t _ratio;
|
||||||
|
|
||||||
|
enum _order _order;
|
||||||
|
bool _right_priority;
|
||||||
|
|
||||||
stack_t stack;
|
stack_t stack;
|
||||||
queue_t queue;
|
queue_t queue;
|
||||||
|
|
||||||
struct _iterator _iter;
|
struct _iterator _iter;
|
||||||
|
|
||||||
bool (*_rebalance)(struct _tree* self, struct _tree_node* root);
|
|
||||||
void (*_destory)(struct _tree* self);
|
void (*_destory)(struct _tree* self);
|
||||||
|
|
||||||
// -------------------- public --------------------
|
// -------------------- public --------------------
|
||||||
// kernel
|
// kernel
|
||||||
bool (*insert)(struct _tree* self, void* obj);
|
bool (*insert)(struct _tree* self, void* obj);
|
||||||
bool (*delete)(struct _tree* self, void* obj);
|
bool (*delete)(struct _tree* self, void* obj);
|
||||||
uint32_t (*height)(struct _tree* self);
|
bool (*rebalance)(struct _tree* self, struct _tree_node* root);
|
||||||
|
int32_t (*height)(struct _tree* self, struct _tree_node* root);
|
||||||
|
|
||||||
// base
|
// base
|
||||||
bool (*clear)(struct _tree* self);
|
bool (*clear)(struct _tree* self);
|
||||||
@ -79,7 +94,7 @@ struct _tree
|
|||||||
uint32_t (*size)(struct _tree* self);
|
uint32_t (*size)(struct _tree* self);
|
||||||
|
|
||||||
// iter
|
// iter
|
||||||
iterator_t (*iter)(struct _tree* self, enum _tree_order);
|
iterator_t (*iter)(struct _tree* self, enum _order);
|
||||||
|
|
||||||
// others
|
// others
|
||||||
bool (*min)(struct _tree* self, void* obj);
|
bool (*min)(struct _tree* self, void* obj);
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
#ifndef _UNICSTL_CONFIG_H_
|
#ifndef _UNICSTL_CONFIG_H_
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief unicstl contains which module
|
* @brief unicstl container
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#define UNICSTL_LIST
|
#define UNICSTL_LIST
|
||||||
@ -27,7 +27,7 @@
|
|||||||
* @brief debug
|
* @brief debug
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
// #define NDEBUG // assert disable
|
#define NDEBUG // assert disable
|
||||||
|
|
||||||
#define UNICSTL_DEBUG
|
#define UNICSTL_DEBUG
|
||||||
|
|
||||||
@ -38,6 +38,7 @@
|
|||||||
#define UNICSTL_DEBUG_TREE
|
#define UNICSTL_DEBUG_TREE
|
||||||
#define UNICSTL_DEBUG_HEAP
|
#define UNICSTL_DEBUG_HEAP
|
||||||
#define UNICSTL_DEBUG_GRAPH
|
#define UNICSTL_DEBUG_GRAPH
|
||||||
|
// #define UNICSTL_DEBUG_ITERATOR
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
133
src/deque.c
133
src/deque.c
@ -198,6 +198,26 @@ static bool deque_front(struct _deque* self, void* obj)
|
|||||||
return true;
|
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)
|
static bool deque_clear(struct _deque* self)
|
||||||
{
|
{
|
||||||
while (!self->empty(self))
|
while (!self->empty(self))
|
||||||
@ -207,6 +227,38 @@ static bool deque_clear(struct _deque* self)
|
|||||||
return true;
|
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)
|
static uint32_t deque_size(struct _deque* self)
|
||||||
{
|
{
|
||||||
assert(self != NULL);
|
assert(self != NULL);
|
||||||
@ -243,13 +295,24 @@ 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)
|
bool deque_iter_hasnext(struct _iterator* iter)
|
||||||
{
|
{
|
||||||
assert(iter != NULL);
|
assert(iter != NULL);
|
||||||
assert(iter->_container != NULL);
|
assert(iter->parent != NULL);
|
||||||
|
|
||||||
deque_t self = (deque_t)iter->_container;
|
deque_t self = (deque_t)iter->_parent;
|
||||||
if(iter->_index < self->size(self))
|
if(iter->_cur < self->size(self))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -259,53 +322,22 @@ bool deque_iter_hasnext(struct _iterator* iter)
|
|||||||
const void* deque_iter_next(struct _iterator* iter)
|
const void* deque_iter_next(struct _iterator* iter)
|
||||||
{
|
{
|
||||||
assert(iter != NULL);
|
assert(iter != NULL);
|
||||||
assert(iter->_container != NULL);
|
assert(iter->parent != NULL);
|
||||||
|
|
||||||
deque_t self = (deque_t)iter->_container;
|
deque_t self = (deque_t)iter->_parent;
|
||||||
void *obj = NULL;
|
void *obj = NULL;
|
||||||
|
|
||||||
struct _deque_node * cur_node = (struct _deque_node *)iter->_node;
|
// base on linklist
|
||||||
if(cur_node == NULL)
|
struct _deque_node * node = (struct _deque_node *)iter->_cur_node;
|
||||||
|
if(node != NULL)
|
||||||
{
|
{
|
||||||
return NULL;
|
obj = node->obj;
|
||||||
|
iter->_cur_node = node->next;
|
||||||
}
|
}
|
||||||
|
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;
|
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)
|
static bool deque_init(struct _deque* self, uint32_t obj_size)
|
||||||
{
|
{
|
||||||
assert(self != NULL);
|
assert(self != NULL);
|
||||||
@ -322,6 +354,9 @@ static bool deque_init(struct _deque* self, uint32_t obj_size)
|
|||||||
self->_head = NULL;
|
self->_head = NULL;
|
||||||
self->_tail = NULL;
|
self->_tail = NULL;
|
||||||
|
|
||||||
|
self->_iter.hasnext = deque_iter_hasnext;
|
||||||
|
self->_iter.next = deque_iter_next;
|
||||||
|
|
||||||
self->_destory = deque_destory;
|
self->_destory = deque_destory;
|
||||||
|
|
||||||
// -------------------- public --------------------
|
// -------------------- public --------------------
|
||||||
@ -332,15 +367,25 @@ static bool deque_init(struct _deque* self, uint32_t obj_size)
|
|||||||
self->pop_front = deque_pop_front;
|
self->pop_front = deque_pop_front;
|
||||||
self->back = deque_back;
|
self->back = deque_back;
|
||||||
self->front = deque_front;
|
self->front = deque_front;
|
||||||
|
self->empty = deque_empty;
|
||||||
|
|
||||||
// base
|
// base
|
||||||
self->clear = deque_clear;
|
self->clear = deque_clear;
|
||||||
self->size = deque_size;
|
self->size = deque_size;
|
||||||
self->empty = deque_empty;
|
|
||||||
|
|
||||||
// iter
|
// iter
|
||||||
self->iter = deque_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 --------------------
|
// -------------------- debug --------------------
|
||||||
self->print = deque_print;
|
self->print = deque_print;
|
||||||
|
|
||||||
|
120
src/graph.c
120
src/graph.c
@ -822,13 +822,59 @@ static struct _graph_node * graph_find_next_unvisited_target(struct _graph *self
|
|||||||
return NULL;
|
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)
|
bool graph_iter_hasnext(struct _iterator *iter)
|
||||||
{
|
{
|
||||||
assert(iter != NULL);
|
assert(iter != NULL);
|
||||||
assert(iter->_container != NULL);
|
assert(iter->parent != NULL);
|
||||||
|
|
||||||
graph_t self = (graph_t)iter->_container;
|
graph_t self = (graph_t)iter->_parent;
|
||||||
if (iter->_index < self->size(self))
|
if (iter->_cur < self->size(self))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -838,16 +884,17 @@ bool graph_iter_hasnext(struct _iterator *iter)
|
|||||||
const void *graph_iter_next(struct _iterator *iter)
|
const void *graph_iter_next(struct _iterator *iter)
|
||||||
{
|
{
|
||||||
assert(iter != NULL);
|
assert(iter != NULL);
|
||||||
assert(iter->_container != NULL);
|
assert(iter->parent != NULL);
|
||||||
graph_t self = (graph_t)iter->_container;
|
|
||||||
|
graph_t self = (graph_t)iter->_parent;
|
||||||
void *obj = NULL;
|
void *obj = NULL;
|
||||||
|
|
||||||
iter->_index += 1;
|
iter->_cur += 1;
|
||||||
switch (self->_search)
|
switch (self->_search)
|
||||||
{
|
{
|
||||||
case GRAPH_BFS:
|
case GRAPH_BFS:
|
||||||
{
|
{
|
||||||
struct _graph_node *cur_node = iter->_node;
|
struct _graph_node *cur_node = iter->_cur_node;
|
||||||
struct _graph_edge *cur_edge = cur_node->edgehead;
|
struct _graph_edge *cur_edge = cur_node->edgehead;
|
||||||
struct _graph_node *target = NULL;
|
struct _graph_node *target = NULL;
|
||||||
struct _graph_node *node = cur_node;
|
struct _graph_node *node = cur_node;
|
||||||
@ -886,13 +933,14 @@ const void *graph_iter_next(struct _iterator *iter)
|
|||||||
cur_node = node;
|
cur_node = node;
|
||||||
}
|
}
|
||||||
|
|
||||||
iter->_node = cur_node;
|
iter->_cur_node = cur_node;
|
||||||
obj = cur_node->obj;
|
obj = cur_node->obj;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GRAPH_DFS:
|
case GRAPH_DFS:
|
||||||
{
|
{
|
||||||
struct _graph_node *cur_node = iter->_node;
|
// self->stack->push(self->stack, iter->_cur_node);
|
||||||
|
struct _graph_node *cur_node = self->_iter._cur_node;
|
||||||
struct _graph_node *node = NULL;
|
struct _graph_node *node = NULL;
|
||||||
|
|
||||||
stack_t stack = self->stack;
|
stack_t stack = self->stack;
|
||||||
@ -928,7 +976,7 @@ const void *graph_iter_next(struct _iterator *iter)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
iter->_node = cur_node;
|
iter->_cur_node = cur_node;
|
||||||
obj = node->obj;
|
obj = node->obj;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -941,55 +989,6 @@ const void *graph_iter_next(struct _iterator *iter)
|
|||||||
return obj;
|
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)
|
static bool graph_init(struct _graph *self, uint32_t obj_size)
|
||||||
{
|
{
|
||||||
assert(self != NULL);
|
assert(self != NULL);
|
||||||
@ -1031,6 +1030,9 @@ static bool graph_init(struct _graph *self, uint32_t obj_size)
|
|||||||
self->_type = GRAPH_UNDIRECTED;
|
self->_type = GRAPH_UNDIRECTED;
|
||||||
// self->_type = GRAPH_DIRECTED;
|
// self->_type = GRAPH_DIRECTED;
|
||||||
|
|
||||||
|
self->_iter.hasnext = graph_iter_hasnext;
|
||||||
|
self->_iter.next = graph_iter_next;
|
||||||
|
|
||||||
self->_destory = graph_destory;
|
self->_destory = graph_destory;
|
||||||
|
|
||||||
// -------------------- public --------------------
|
// -------------------- public --------------------
|
||||||
|
43
src/heap.c
43
src/heap.c
@ -249,13 +249,25 @@ 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)
|
bool heap_iter_hasnext(struct _iterator* iter)
|
||||||
{
|
{
|
||||||
assert(iter != NULL);
|
assert(iter != NULL);
|
||||||
assert(iter->_container != NULL);
|
assert(iter->parent != NULL);
|
||||||
|
|
||||||
heap_t self = (heap_t)iter->_container;
|
heap_t self = (heap_t)iter->_parent;
|
||||||
if(iter->_index < self->size(self))
|
if(iter->_cur < self->size(self))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -265,32 +277,18 @@ bool heap_iter_hasnext(struct _iterator* iter)
|
|||||||
const void* heap_iter_next(struct _iterator* iter)
|
const void* heap_iter_next(struct _iterator* iter)
|
||||||
{
|
{
|
||||||
assert(iter != NULL);
|
assert(iter != NULL);
|
||||||
assert(iter->_container != NULL);
|
assert(iter->parent != NULL);
|
||||||
|
|
||||||
heap_t self = (heap_t)iter->_container;
|
heap_t self = (heap_t)iter->_parent;
|
||||||
void *obj = NULL;
|
void *obj = NULL;
|
||||||
|
|
||||||
uint32_t index = iter->_index;
|
uint32_t index = self->_iter._cur;
|
||||||
obj = self->obj + self->_obj_size * index;
|
obj = self->obj + self->_obj_size * index;
|
||||||
|
|
||||||
iter->_index += 1;
|
self->_iter._cur += 1;
|
||||||
return obj;
|
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)
|
static bool heap_init2(struct _heap* self, uint32_t obj_size, uint32_t capacity)
|
||||||
{
|
{
|
||||||
assert(self != NULL);
|
assert(self != NULL);
|
||||||
@ -307,6 +305,9 @@ static bool heap_init2(struct _heap* self, uint32_t obj_size, uint32_t capacity)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self->_iter.hasnext = heap_iter_hasnext;
|
||||||
|
self->_iter.next = heap_iter_next;
|
||||||
|
|
||||||
self->_destory = heap_destory;
|
self->_destory = heap_destory;
|
||||||
|
|
||||||
// -------------------- public --------------------
|
// -------------------- public --------------------
|
||||||
|
322
src/list.c
322
src/list.c
@ -1,29 +1,48 @@
|
|||||||
/**
|
/**
|
||||||
* @file list.c
|
* @file list.c
|
||||||
* @author wenjf (Orig5826@163.com)
|
* @author wenjf (Orig5826@163.com)
|
||||||
* @brief
|
* @brief
|
||||||
* @version 0.1
|
* @version 0.1
|
||||||
* @date 2024-06-23
|
* @date 2024-06-23
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2024
|
* @copyright Copyright (c) 2024
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
|
|
||||||
|
static bool list_append(struct _list* self, void* obj)
|
||||||
static bool list_insert(struct _list* self, int index, void* obj)
|
|
||||||
{
|
{
|
||||||
// assert(index >= 0 && index < (int)self->size(self));
|
assert(self != NULL);
|
||||||
// assert(index >= 0 && index <= (int)self->size(self));
|
assert(self->obj != NULL);
|
||||||
if (index < 0 || index >(int)self->size(self))
|
assert(obj != NULL);
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self->size(self) == self->_capacity)
|
if (self->size(self) == self->_capacity)
|
||||||
{
|
{
|
||||||
int capacity = self->_capacity * self->_ratio;
|
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;
|
||||||
|
}
|
||||||
|
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));
|
||||||
|
|
||||||
|
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)
|
if (obj_new == NULL)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@ -33,24 +52,16 @@ static bool list_insert(struct _list* self, int index, void* obj)
|
|||||||
}
|
}
|
||||||
uint32_t offset = index * self->_obj_size;
|
uint32_t offset = index * self->_obj_size;
|
||||||
uint32_t offset1 = (index + 1) * self->_obj_size;
|
uint32_t offset1 = (index + 1) * self->_obj_size;
|
||||||
uint32_t count = self->size(self) - index;
|
|
||||||
|
|
||||||
// move data to right
|
memmove((char*)self->obj + offset, (char*)self->obj + offset, self->size(self) * self->_obj_size);
|
||||||
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;
|
self->_size += 1;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool list_delete(struct _list* self, int index, void* obj)
|
static bool list_pop(struct _list* self, int index, void* obj)
|
||||||
{
|
{
|
||||||
assert(self != NULL);
|
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))
|
if (self->empty(self))
|
||||||
{
|
{
|
||||||
@ -62,9 +73,9 @@ static bool list_delete(struct _list* self, int index, void* obj)
|
|||||||
index += self->size(self);
|
index += self->size(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t count = self->size(self) - 1 - index;
|
||||||
uint32_t offset = index * self->_obj_size;
|
uint32_t offset = index * self->_obj_size;
|
||||||
uint32_t offset1 = (index + 1) * self->_obj_size;
|
uint32_t offset1 = (index + 1) * self->_obj_size;
|
||||||
uint32_t count = self->size(self) - 1 - index;
|
|
||||||
if (obj != NULL)
|
if (obj != NULL)
|
||||||
{
|
{
|
||||||
memmove(obj, (char*)self->obj + offset, self->_obj_size);
|
memmove(obj, (char*)self->obj + offset, self->_obj_size);
|
||||||
@ -74,39 +85,15 @@ static bool list_delete(struct _list* self, int index, void* obj)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool list_append(struct _list* self, void* obj)
|
|
||||||
{
|
|
||||||
return self->insert(self, (int)self->size(self), 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)
|
static int list_index(struct _list* self, void* obj)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool list_remove(struct _list* self, void* obj)
|
||||||
{
|
{
|
||||||
assert(self != NULL);
|
assert(self != NULL);
|
||||||
int index = 0;
|
return true;
|
||||||
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)
|
static bool list_clear(struct _list* self)
|
||||||
@ -146,22 +133,25 @@ static bool list_set(struct _list* self, int index, void* obj)
|
|||||||
|
|
||||||
static uint32_t list_size(struct _list* self)
|
static uint32_t list_size(struct _list* self)
|
||||||
{
|
{
|
||||||
assert(self != NULL);
|
|
||||||
return self->_size;
|
return self->_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t list_capacity(struct _list* self)
|
|
||||||
{
|
|
||||||
assert(self != NULL);
|
|
||||||
return self->_capacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool list_empty(struct _list* self)
|
static bool list_empty(struct _list* self)
|
||||||
{
|
{
|
||||||
assert(self != NULL);
|
assert(self != NULL);
|
||||||
return !self->size(self);
|
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
|
// free
|
||||||
static void list_destory(struct _list* self)
|
static void list_destory(struct _list* self)
|
||||||
{
|
{
|
||||||
@ -189,185 +179,38 @@ static void list_print(struct _list* self)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int list_index_exchange(struct _list* self, int index)
|
static const void* list_iter_next(struct _iterator* iter)
|
||||||
{
|
{
|
||||||
assert(self != NULL);
|
list_t self = (list_t)iter->_parent;
|
||||||
int size = (int)self->size(self);
|
void *obj = self->obj + self->_iter._cur * self->_obj_size;
|
||||||
|
self->_iter._cur += 1;
|
||||||
if (index < 0)
|
return obj;
|
||||||
{
|
|
||||||
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)
|
static bool list_iter_hasnext(struct _iterator* iter)
|
||||||
{
|
{
|
||||||
list_t self = (list_t)iter->_container;
|
list_t self = (list_t)iter->_parent;
|
||||||
|
|
||||||
if (iter->_index < self->size(self))
|
if(self->_iter._cur < self->size(self))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
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)
|
iterator_t list_iter(struct _list* self)
|
||||||
{
|
{
|
||||||
assert(self != NULL);
|
self->_iter._parent = self;
|
||||||
iterator_t iter = &self->_iter;
|
self->_iter._cur = 0;
|
||||||
|
return &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)
|
static bool list_init2(struct _list* list, uint32_t obj_size, uint32_t capacity)
|
||||||
{
|
{
|
||||||
assert(list != NULL);
|
assert(list != NULL);
|
||||||
if (list == NULL || obj_size == 0 || capacity == 0)
|
assert(obj_size > 0);
|
||||||
|
assert(capacity > 0);
|
||||||
|
if(list == NULL || obj_size == 0 || capacity == 0)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -393,35 +236,30 @@ static bool list_init2(struct _list* list, uint32_t obj_size, uint32_t capacity)
|
|||||||
// -------------------- public --------------------
|
// -------------------- public --------------------
|
||||||
// kernel
|
// kernel
|
||||||
list->append = list_append;
|
list->append = list_append;
|
||||||
|
list->insert = list_insert;
|
||||||
list->pop = list_pop;
|
list->pop = list_pop;
|
||||||
|
|
||||||
list->insert = list_insert;
|
list->empty = list_empty;
|
||||||
list->delete = list_delete;
|
|
||||||
|
|
||||||
list->get = list_get;
|
|
||||||
list->set = list_set;
|
|
||||||
|
|
||||||
list->index = list_index;
|
|
||||||
// list->contains = list_contains;
|
|
||||||
|
|
||||||
// base
|
// base
|
||||||
list->clear = list_clear;
|
list->clear = list_clear;
|
||||||
list->size = list_size;
|
list->size = list_size;
|
||||||
list->empty = list_empty;
|
|
||||||
list->capacity = list_capacity;
|
|
||||||
|
|
||||||
// iter
|
// iter
|
||||||
list->iter = list_iter;
|
list->iter = list_iter;
|
||||||
|
|
||||||
// others
|
// others
|
||||||
list->slice = list_slice;
|
list->index = list_index;
|
||||||
|
list->remove = list_remove;
|
||||||
|
list->get = list_get;
|
||||||
|
list->set = list_set;
|
||||||
|
|
||||||
// config
|
// list->reverse = list_reverse;
|
||||||
list->compare = default_compare;
|
// list->sort = list_sort;
|
||||||
// -------------------- debug --------------------
|
|
||||||
list->print_obj = default_print_obj;
|
// -------------------- debug --------------------
|
||||||
list->print = list_print;
|
list->print = list_print;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -429,12 +267,12 @@ list_t list_new2(uint32_t obj_size, uint32_t capacity)
|
|||||||
{
|
{
|
||||||
struct _list* list = NULL;
|
struct _list* list = NULL;
|
||||||
list = (struct _list*)calloc(1, sizeof(struct _list));
|
list = (struct _list*)calloc(1, sizeof(struct _list));
|
||||||
if (list == NULL)
|
if(list == NULL)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (list_init2(list, obj_size, capacity) != true)
|
if(list_init2(list, obj_size, capacity) != true)
|
||||||
{
|
{
|
||||||
free(list);
|
free(list);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -445,9 +283,9 @@ list_t list_new2(uint32_t obj_size, uint32_t capacity)
|
|||||||
void list_free(list_t* list)
|
void list_free(list_t* list)
|
||||||
{
|
{
|
||||||
assert(list != NULL);
|
assert(list != NULL);
|
||||||
if (list != NULL && *list != NULL)
|
if(list != NULL && *list != NULL)
|
||||||
{
|
{
|
||||||
if ((*list)->_destory != NULL)
|
if((*list)->_destory != NULL)
|
||||||
{
|
{
|
||||||
(*list)->_destory(*list);
|
(*list)->_destory(*list);
|
||||||
}
|
}
|
||||||
|
72
src/queue.c
72
src/queue.c
@ -306,13 +306,24 @@ 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)
|
static bool queue_iter_hasnext(struct _iterator* iter)
|
||||||
{
|
{
|
||||||
assert(iter != NULL);
|
assert(iter != NULL);
|
||||||
assert(iter->_container != NULL);
|
assert(iter->parent != NULL);
|
||||||
|
|
||||||
queue_t self = (queue_t)iter->_container;
|
queue_t self = (queue_t)iter->_parent;
|
||||||
if(iter->_index < self->size(self))
|
if(iter->_cur < self->size(self))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -322,69 +333,42 @@ static bool queue_iter_hasnext(struct _iterator* iter)
|
|||||||
static const void* queue_iter_next(struct _iterator* iter)
|
static const void* queue_iter_next(struct _iterator* iter)
|
||||||
{
|
{
|
||||||
assert(iter != NULL);
|
assert(iter != NULL);
|
||||||
assert(iter->_container != NULL);
|
assert(iter->parent != NULL);
|
||||||
|
|
||||||
queue_t self = (queue_t)iter->_container;
|
queue_t self = (queue_t)iter->_parent;
|
||||||
void *obj = NULL;
|
void *obj = NULL;
|
||||||
|
|
||||||
// base on linklist
|
// base on linklist
|
||||||
struct _queue_node * node = (struct _queue_node *)iter->_node;
|
struct _queue_node * node = (struct _queue_node *)iter->_cur_node;
|
||||||
if(node != NULL)
|
if(node != NULL)
|
||||||
{
|
{
|
||||||
obj = node->obj;
|
obj = node->obj;
|
||||||
iter->_node = node->next;
|
iter->_cur_node = node->next;
|
||||||
}
|
}
|
||||||
iter->_index += 1;
|
self->_iter._cur += 1;
|
||||||
return obj;
|
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)
|
static const void* queue2_iter_next(struct _iterator* iter)
|
||||||
{
|
{
|
||||||
assert(iter != NULL);
|
assert(iter != NULL);
|
||||||
assert(iter->_container != NULL);
|
assert(iter->parent != NULL);
|
||||||
|
|
||||||
queue_t self = (queue_t)iter->_container;
|
queue_t self = (queue_t)iter->_parent;
|
||||||
void *obj = NULL;
|
void *obj = NULL;
|
||||||
|
|
||||||
// base on array
|
// base on array
|
||||||
uint32_t index = iter->_index;
|
uint32_t index = self->_iter._cur;
|
||||||
obj = self->_front->obj + self->_obj_size * index;
|
obj = self->_front->obj + self->_obj_size * index;
|
||||||
|
|
||||||
iter->_index += 1;
|
self->_iter._cur += 1;
|
||||||
return obj;
|
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)
|
static bool queue_init(struct _queue * self, uint32_t obj_size)
|
||||||
{
|
{
|
||||||
assert(self != NULL);
|
assert(self != NULL);
|
||||||
|
assert(obj_size > 0);
|
||||||
if(self == NULL || obj_size == 0)
|
if(self == NULL || obj_size == 0)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@ -403,6 +387,10 @@ static bool queue_init(struct _queue * self, uint32_t obj_size)
|
|||||||
// base
|
// base
|
||||||
self->_destory = queue_destory;
|
self->_destory = queue_destory;
|
||||||
|
|
||||||
|
// iter
|
||||||
|
self->_iter.hasnext = queue_iter_hasnext;
|
||||||
|
self->_iter.next = queue_iter_next;
|
||||||
|
|
||||||
// -------------------- public --------------------
|
// -------------------- public --------------------
|
||||||
// kernel
|
// kernel
|
||||||
self->push = queue_push;
|
self->push = queue_push;
|
||||||
@ -429,6 +417,8 @@ 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)
|
static bool queue_init2(struct _queue * self, uint32_t obj_size, uint32_t capacity)
|
||||||
{
|
{
|
||||||
assert(self != NULL);
|
assert(self != NULL);
|
||||||
|
assert(obj_size > 0);
|
||||||
|
assert(capacity > 0);
|
||||||
if(self == NULL || obj_size == 0 || capacity == 0)
|
if(self == NULL || obj_size == 0 || capacity == 0)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@ -481,7 +471,7 @@ static bool queue_init2(struct _queue * self, uint32_t obj_size, uint32_t capaci
|
|||||||
self->clear = queue2_clear;
|
self->clear = queue2_clear;
|
||||||
|
|
||||||
// iter
|
// iter
|
||||||
self->iter = queue2_iter;
|
self->iter = queue_iter;
|
||||||
|
|
||||||
// -------------------- debug --------------------
|
// -------------------- debug --------------------
|
||||||
self->print = queue2_print;
|
self->print = queue2_print;
|
||||||
|
92
src/stack.c
92
src/stack.c
@ -254,64 +254,63 @@ 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)
|
bool stack_iter_hasnext(struct _iterator* iter)
|
||||||
{
|
{
|
||||||
assert(iter != NULL);
|
assert(iter != NULL);
|
||||||
assert(iter->_container != NULL);
|
assert(iter->parent != NULL);
|
||||||
|
|
||||||
stack_t self = (stack_t)iter->_container;
|
stack_t self = (stack_t)iter->_parent;
|
||||||
if(iter->_index < self->size(self))
|
if(self->_iter._cur < self->size(self))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
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)
|
iterator_t stack_iter(struct _stack* self)
|
||||||
{
|
{
|
||||||
assert(self != NULL);
|
assert(self != NULL);
|
||||||
iterator_t iter = &self->_iter;
|
self->_iter._parent = self;
|
||||||
|
self->_iter._cur = 0;
|
||||||
iter->_container = self;
|
self->_iter._cur_node = self->_head->next;
|
||||||
iter->_index = 0;
|
return &self->_iter;
|
||||||
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)
|
static bool stack_init(struct _stack* self, uint32_t obj_size)
|
||||||
@ -337,6 +336,9 @@ static bool stack_init(struct _stack* self, uint32_t obj_size)
|
|||||||
self->_head->obj = NULL;
|
self->_head->obj = NULL;
|
||||||
self->_head->next = NULL;
|
self->_head->next = NULL;
|
||||||
|
|
||||||
|
self->_iter.next = stack_iter_next;
|
||||||
|
self->_iter.hasnext = stack_iter_hasnext;
|
||||||
|
|
||||||
self->_destory = stack_destory;
|
self->_destory = stack_destory;
|
||||||
|
|
||||||
// ---------- public ----------
|
// ---------- public ----------
|
||||||
|
935
src/tree.c
935
src/tree.c
File diff suppressed because it is too large
Load Diff
@ -1,23 +0,0 @@
|
|||||||
/**
|
|
||||||
* @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);
|
|
||||||
}
|
|
@ -113,7 +113,6 @@ static void test_deque_num(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
for (i = 0; i < len; i++)
|
for (i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
TEST_ASSERT_TRUE(deque->push_front(deque, &data[i]));
|
TEST_ASSERT_TRUE(deque->push_front(deque, &data[i]));
|
||||||
@ -131,7 +130,6 @@ static void test_deque_num(void)
|
|||||||
{
|
{
|
||||||
TEST_ASSERT_TRUE(deque->get(deque, i, &temp));
|
TEST_ASSERT_TRUE(deque->get(deque, i, &temp));
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
deque_free(&deque);
|
deque_free(&deque);
|
||||||
TEST_ASSERT_NULL(deque);
|
TEST_ASSERT_NULL(deque);
|
||||||
@ -256,12 +254,10 @@ static void test_deque_struct(void)
|
|||||||
TEST_ASSERT_TRUE(deque->push_front(deque, &data[i]));
|
TEST_ASSERT_TRUE(deque->push_front(deque, &data[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
for (i = 0; i < len; i++)
|
for (i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
TEST_ASSERT_TRUE(deque->get(deque, i, &temp));
|
TEST_ASSERT_TRUE(deque->get(deque, i, &temp));
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
deque_free(&deque);
|
deque_free(&deque);
|
||||||
TEST_ASSERT_NULL(deque);
|
TEST_ASSERT_NULL(deque);
|
||||||
@ -271,7 +267,7 @@ static void test_deque_struct(void)
|
|||||||
static void test_deque_iter(void)
|
static void test_deque_iter(void)
|
||||||
{
|
{
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
int data[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
int data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||||
int temp = 0;
|
int temp = 0;
|
||||||
uint32_t len = sizeof(data) / sizeof(data[0]);
|
uint32_t len = sizeof(data) / sizeof(data[0]);
|
||||||
|
|
||||||
@ -292,33 +288,26 @@ static void test_deque_iter(void)
|
|||||||
TEST_ASSERT_EQUAL_INT(i + 1, deque->size(deque));
|
TEST_ASSERT_EQUAL_INT(i + 1, deque->size(deque));
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator_t iter = deque->iter(deque, DEQUE_FORWARD);
|
iterator_t iter = deque->iter(deque);
|
||||||
i = 0;
|
i = 0;
|
||||||
while(iter->hasnext(iter))
|
while(iter->hasnext(iter))
|
||||||
{
|
{
|
||||||
temp = *(int *)iter->next(iter);
|
temp = *(int *)iter->next(iter);
|
||||||
|
// printf("%d ", temp);
|
||||||
TEST_ASSERT_EQUAL_INT(data[i], temp);
|
TEST_ASSERT_EQUAL_INT(data[i], temp);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
iter = deque->iter(deque, DEQUE_FORWARD);
|
iter = deque->iter(deque);
|
||||||
i = 0;
|
i = 0;
|
||||||
while(iter->hasnext(iter))
|
while(iter->hasnext(iter))
|
||||||
{
|
{
|
||||||
temp = *(int *)iter->next(iter);
|
temp = *(int *)iter->next(iter);
|
||||||
|
// printf("%d ", temp);
|
||||||
TEST_ASSERT_EQUAL_INT(data[i], temp);
|
TEST_ASSERT_EQUAL_INT(data[i], temp);
|
||||||
i++;
|
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);
|
deque_free(&deque);
|
||||||
TEST_ASSERT_NULL(deque);
|
TEST_ASSERT_NULL(deque);
|
||||||
}
|
}
|
||||||
|
@ -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[7], &data[6], 87));
|
||||||
TEST_ASSERT_TRUE(graph->add_edge(graph, &data[8], &data[2], 92));
|
TEST_ASSERT_TRUE(graph->add_edge(graph, &data[8], &data[2], 92));
|
||||||
TEST_ASSERT_FALSE(graph->add_edge(graph, &temp, &data[1], 0));
|
TEST_ASSERT_FALSE(graph->add_edge(graph, &temp, &data[1], 0));
|
||||||
// graph->print(graph);
|
graph->print(graph);
|
||||||
|
|
||||||
iterator_t iter_vertex = NULL;
|
iterator_t iter_vertex = NULL;
|
||||||
|
|
||||||
@ -158,18 +158,18 @@ void test_graph_iter(void)
|
|||||||
while(iter_vertex->hasnext(iter_vertex))
|
while(iter_vertex->hasnext(iter_vertex))
|
||||||
{
|
{
|
||||||
temp = *(int *)iter_vertex->next(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]);
|
iter_vertex = graph->iter(graph, GRAPH_DFS, &data[0]);
|
||||||
TEST_ASSERT_NOT_NULL(iter_vertex);
|
TEST_ASSERT_NOT_NULL(iter_vertex);
|
||||||
while(iter_vertex->hasnext(iter_vertex))
|
while(iter_vertex->hasnext(iter_vertex))
|
||||||
{
|
{
|
||||||
temp = *(int *)iter_vertex->next(iter_vertex);
|
temp = *(int *)iter_vertex->next(iter_vertex);
|
||||||
//graph->print_obj(&temp);
|
graph->print_obj(&temp);
|
||||||
}
|
}
|
||||||
//printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
graph_free(&graph);
|
graph_free(&graph);
|
||||||
TEST_ASSERT_NULL(graph);
|
TEST_ASSERT_NULL(graph);
|
||||||
|
539
test/test_list.c
539
test/test_list.c
@ -1,12 +1,12 @@
|
|||||||
/**
|
/**
|
||||||
* @file test_list->c
|
* @file test_list->c
|
||||||
* @author wenjf (Orig5826@163.com)
|
* @author wenjf (Orig5826@163.com)
|
||||||
* @brief
|
* @brief
|
||||||
* @version 0.1
|
* @version 0.1
|
||||||
* @date 2024-08-30
|
* @date 2024-08-30
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2024
|
* @copyright Copyright (c) 2024
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#include "test.h"
|
#include "test.h"
|
||||||
|
|
||||||
@ -15,7 +15,7 @@ static void test_list_new(void)
|
|||||||
list_t list = NULL;
|
list_t list = NULL;
|
||||||
list = list_new2(sizeof(int), 1);
|
list = list_new2(sizeof(int), 1);
|
||||||
TEST_ASSERT_NOT_NULL(list);
|
TEST_ASSERT_NOT_NULL(list);
|
||||||
list_free(&list);
|
list_free(&list);
|
||||||
TEST_ASSERT_NULL(list);
|
TEST_ASSERT_NULL(list);
|
||||||
|
|
||||||
list_free(&list); // list_free(NULL);
|
list_free(&list); // list_free(NULL);
|
||||||
@ -26,6 +26,7 @@ static void test_list_new(void)
|
|||||||
TEST_ASSERT_NULL(list_new2(sizeof(int), 0));
|
TEST_ASSERT_NULL(list_new2(sizeof(int), 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void test_list_append(void)
|
static void test_list_append(void)
|
||||||
{
|
{
|
||||||
int temp = 0;
|
int temp = 0;
|
||||||
@ -38,7 +39,7 @@ static void test_list_append(void)
|
|||||||
// ------------------------------
|
// ------------------------------
|
||||||
list = list_new2(sizeof(int), len);
|
list = list_new2(sizeof(int), len);
|
||||||
TEST_ASSERT_TRUE(list->empty(list));
|
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_TRUE(list->append(list, &data[i]));
|
||||||
TEST_ASSERT_EQUAL_INT(i + 1, list->size(list));
|
TEST_ASSERT_EQUAL_INT(i + 1, list->size(list));
|
||||||
@ -53,7 +54,7 @@ static void test_list_append(void)
|
|||||||
// ------------------------------
|
// ------------------------------
|
||||||
// if capacity is less than data len
|
// if capacity is less than data len
|
||||||
list = list_new2(sizeof(int), len - 2);
|
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_TRUE(list->append(list, &data[i]));
|
||||||
TEST_ASSERT_EQUAL_INT(i + 1, list->size(list));
|
TEST_ASSERT_EQUAL_INT(i + 1, list->size(list));
|
||||||
@ -61,6 +62,7 @@ static void test_list_append(void)
|
|||||||
list_free(&list);
|
list_free(&list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void test_list_pop(void)
|
static void test_list_pop(void)
|
||||||
{
|
{
|
||||||
int temp = 0;
|
int temp = 0;
|
||||||
@ -72,91 +74,19 @@ static void test_list_pop(void)
|
|||||||
|
|
||||||
// ------------------------------
|
// ------------------------------
|
||||||
list = list_new2(sizeof(int), len);
|
list = list_new2(sizeof(int), len);
|
||||||
for (i = 0; i < len; i++)
|
for(i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
list->append(list, &data[i]);
|
list->append(list, &data[i]);
|
||||||
}
|
}
|
||||||
for (i = 0; i < len; i++)
|
for (i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
TEST_ASSERT_TRUE(list->pop(list, &temp));
|
TEST_ASSERT_TRUE(list->pop(list, 0, &temp));
|
||||||
}
|
}
|
||||||
TEST_ASSERT_TRUE(list->empty(list));
|
TEST_ASSERT_TRUE(list->empty(list));
|
||||||
TEST_ASSERT_FALSE(list->pop(list, &temp));
|
// TEST_ASSERT_FALSE(list->pop(list, 1, &temp));
|
||||||
list_free(&list);
|
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)
|
static void test_list_clear(void)
|
||||||
{
|
{
|
||||||
@ -170,7 +100,7 @@ static void test_list_clear(void)
|
|||||||
// ------------------------------
|
// ------------------------------
|
||||||
list = list_new2(sizeof(int), len);
|
list = list_new2(sizeof(int), len);
|
||||||
TEST_ASSERT_TRUE(list->clear(list));
|
TEST_ASSERT_TRUE(list->clear(list));
|
||||||
for (i = 0; i < len; i++)
|
for(i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
list->append(list, &data[i]);
|
list->append(list, &data[i]);
|
||||||
}
|
}
|
||||||
@ -199,9 +129,9 @@ static void test_list_num(void)
|
|||||||
{
|
{
|
||||||
TEST_ASSERT_TRUE(list->append(list, &data[i]));
|
TEST_ASSERT_TRUE(list->append(list, &data[i]));
|
||||||
}
|
}
|
||||||
TEST_ASSERT_TRUE(list->delete(list, 9, NULL));
|
TEST_ASSERT_TRUE(list->pop(list, 9, NULL));
|
||||||
TEST_ASSERT_TRUE(list->delete(list, 0, NULL));
|
TEST_ASSERT_TRUE(list->pop(list, 0, NULL));
|
||||||
TEST_ASSERT_TRUE(list->delete(list, 4, NULL));
|
TEST_ASSERT_TRUE(list->pop(list, 4, NULL));
|
||||||
TEST_ASSERT_TRUE(list->clear(list));
|
TEST_ASSERT_TRUE(list->clear(list));
|
||||||
|
|
||||||
for (i = 0; i < len; i++)
|
for (i = 0; i < len; i++)
|
||||||
@ -252,7 +182,7 @@ static void test_list_num(void)
|
|||||||
|
|
||||||
for (i = 0; i < len + 1; i++)
|
for (i = 0; i < len + 1; i++)
|
||||||
{
|
{
|
||||||
TEST_ASSERT_TRUE(list->pop(list, &temp));
|
TEST_ASSERT_TRUE(list->pop(list, 0, &temp));
|
||||||
|
|
||||||
if (list->empty(list))
|
if (list->empty(list))
|
||||||
{
|
{
|
||||||
@ -269,10 +199,10 @@ static void test_list_struct(void)
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
struct _student data[] = {
|
struct _student data[] = {
|
||||||
"zhao", 1001, "qian", 1002, "sun", 1003, "li", 1004,
|
"zhao", 1001, "qian", 1002, "sun", 1003, "li", 1004,
|
||||||
"zhou", 1005, "wu", 1006, "zheng", 1007, "wang", 1008,
|
"zhou", 1005, "wu", 1006, "zheng", 1007, "wang", 1008,
|
||||||
"feng", 1009, "cheng",1010,
|
"feng", 1009, "cheng",1010,
|
||||||
};
|
};
|
||||||
struct _student temp = { 0 };
|
struct _student temp = {0};
|
||||||
int index = 0;
|
int index = 0;
|
||||||
int len = sizeof(data) / sizeof(data[0]);
|
int len = sizeof(data) / sizeof(data[0]);
|
||||||
|
|
||||||
@ -283,9 +213,9 @@ static void test_list_struct(void)
|
|||||||
{
|
{
|
||||||
TEST_ASSERT_TRUE(list->append(list, &data[i]));
|
TEST_ASSERT_TRUE(list->append(list, &data[i]));
|
||||||
}
|
}
|
||||||
TEST_ASSERT_TRUE(list->delete(list, 9, NULL));
|
TEST_ASSERT_TRUE(list->pop(list, 9, NULL));
|
||||||
TEST_ASSERT_TRUE(list->delete(list, 0, NULL));
|
TEST_ASSERT_TRUE(list->pop(list, 0, NULL));
|
||||||
TEST_ASSERT_TRUE(list->delete(list, 4, NULL));
|
TEST_ASSERT_TRUE(list->pop(list, 4, NULL));
|
||||||
|
|
||||||
TEST_ASSERT_TRUE(list->clear(list));
|
TEST_ASSERT_TRUE(list->clear(list));
|
||||||
for (i = 0; i < len; i++)
|
for (i = 0; i < len; i++)
|
||||||
@ -337,12 +267,12 @@ static void test_list_struct(void)
|
|||||||
TEST_ASSERT_TRUE(list->set(list, index, &temp));
|
TEST_ASSERT_TRUE(list->set(list, index, &temp));
|
||||||
|
|
||||||
index = -10;
|
index = -10;
|
||||||
temp = (struct _student){ "robot", 97 };
|
temp = (struct _student){"robot", 97};
|
||||||
TEST_ASSERT_TRUE(list->set(list, index, &temp));
|
TEST_ASSERT_TRUE(list->set(list, index, &temp));
|
||||||
|
|
||||||
for (i = 0; i < len + 1; i++)
|
for (i = 0; i < len + 1; i++)
|
||||||
{
|
{
|
||||||
TEST_ASSERT_TRUE(list->pop(list, &temp));
|
TEST_ASSERT_TRUE(list->pop(list, 0, &temp));
|
||||||
|
|
||||||
if (list->empty(list))
|
if (list->empty(list))
|
||||||
{
|
{
|
||||||
@ -354,6 +284,51 @@ static void test_list_struct(void)
|
|||||||
TEST_ASSERT_NULL(list);
|
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)
|
void test_list_iter(void)
|
||||||
{
|
{
|
||||||
int temp = 0;
|
int temp = 0;
|
||||||
@ -368,7 +343,7 @@ void test_list_iter(void)
|
|||||||
TEST_ASSERT_TRUE(list->empty(list));
|
TEST_ASSERT_TRUE(list->empty(list));
|
||||||
list->print_obj = print_num;
|
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_TRUE(list->append(list, &data[i]));
|
||||||
TEST_ASSERT_EQUAL_INT(i + 1, list->size(list));
|
TEST_ASSERT_EQUAL_INT(i + 1, list->size(list));
|
||||||
@ -382,7 +357,7 @@ void test_list_iter(void)
|
|||||||
iterator_t iter = list->iter(list);
|
iterator_t iter = list->iter(list);
|
||||||
int iter_data = 0;
|
int iter_data = 0;
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
while (iter->hasnext(iter))
|
while(iter->hasnext(iter))
|
||||||
{
|
{
|
||||||
iter_data = *(int*)iter->next(iter);
|
iter_data = *(int*)iter->next(iter);
|
||||||
// printf("%d ", iter_data);
|
// printf("%d ", iter_data);
|
||||||
@ -391,389 +366,19 @@ void test_list_iter(void)
|
|||||||
}
|
}
|
||||||
list_free(&list);
|
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)
|
void test_list(void)
|
||||||
{
|
{
|
||||||
UnitySetTestFile(__FILE__);
|
UnitySetTestFile(__FILE__);
|
||||||
|
|
||||||
RUN_TEST(test_list_new);
|
RUN_TEST(test_list_new);
|
||||||
|
|
||||||
RUN_TEST(test_list_append);
|
RUN_TEST(test_list_append);
|
||||||
RUN_TEST(test_list_pop);
|
RUN_TEST(test_list_pop);
|
||||||
RUN_TEST(test_list_insert);
|
|
||||||
RUN_TEST(test_list_delete);
|
|
||||||
|
|
||||||
RUN_TEST(test_list_clear);
|
RUN_TEST(test_list_clear);
|
||||||
|
|
||||||
RUN_TEST(test_list_num);
|
RUN_TEST(test_list_num);
|
||||||
RUN_TEST(test_list_struct);
|
RUN_TEST(test_list_struct);
|
||||||
|
|
||||||
RUN_TEST(test_list_iter);
|
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);
|
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ static const int expected_int_array_orderpre_delete[15][15] = {
|
|||||||
{ 13, },
|
{ 13, },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const enum _tree_order order[8] = {
|
static const enum _order order[8] = {
|
||||||
ORDER_PRE, ORDER_IN, ORDER_POST, ORDER_BREADTH,
|
ORDER_PRE, ORDER_IN, ORDER_POST, ORDER_BREADTH,
|
||||||
ORDER_PRE_R, ORDER_IN_R, ORDER_POST_R, ORDER_BREADTH_R
|
ORDER_PRE_R, ORDER_IN_R, ORDER_POST_R, ORDER_BREADTH_R
|
||||||
};
|
};
|
||||||
@ -335,6 +335,10 @@ static void test_rbtree_delete(void)
|
|||||||
int temp = 0;
|
int temp = 0;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
iterator_t iter = NULL;
|
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));
|
tree_t tree = tree_rb_new(sizeof(int));
|
||||||
TEST_ASSERT_NOT_NULL(tree);
|
TEST_ASSERT_NOT_NULL(tree);
|
||||||
|
Loading…
Reference in New Issue
Block a user