mirror of
https://gitee.com/apaki/unicstl.git
synced 2025-07-05 16:36:54 +08:00
Compare commits
5 Commits
6c74793931
...
98ead745ff
Author | SHA1 | Date | |
---|---|---|---|
98ead745ff | |||
170c2a5421 | |||
349889ea98 | |||
d6811b824c | |||
ee19e77ab8 |
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@ -1,6 +1,6 @@
|
||||
{
|
||||
"cmake.configureOnOpen": true,
|
||||
"files.encoding": "gb18030",
|
||||
"files.encoding": "utf8",
|
||||
"files.associations": {
|
||||
"common.h": "c",
|
||||
"unicstl.h": "c",
|
||||
|
@ -1,11 +1,11 @@
|
||||
|
||||
# 0. cmake 最低版本号要求
|
||||
# 0. cmake 最低版本号要求
|
||||
cmake_minimum_required(VERSION 3.29)
|
||||
|
||||
# 0. 项目信息
|
||||
# 0. 项目信息
|
||||
project(demo VERSION 0.0.01)
|
||||
|
||||
# 2. 支持GDB
|
||||
# 2. 支持GDB
|
||||
set(CMAKE_BUILD_TYPE "Debug")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g --std=c99")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall --std=c99")
|
||||
@ -14,11 +14,11 @@ set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall --std=c99")
|
||||
set(CMAKE_INSTALL_PREFIX "release")
|
||||
|
||||
|
||||
# 1. 添加头文件路径
|
||||
# 1. 添加头文件路径
|
||||
include_directories(include)
|
||||
include_directories(3rdparty/unicstl-unity/src)
|
||||
|
||||
# 1. 添加子目录
|
||||
# 1. 添加子目录
|
||||
add_subdirectory(src)
|
||||
add_subdirectory(demo)
|
||||
add_subdirectory(3rdparty)
|
||||
|
@ -10,7 +10,7 @@
|
||||
*/
|
||||
#include "demo.h"
|
||||
|
||||
// vs2022 ア默<EFBDB1>袁サ
|
||||
// if vs2022 has error: 'max': macro redefinition
|
||||
#ifdef max
|
||||
#undef max
|
||||
#endif
|
||||
|
@ -1,7 +1,6 @@
|
||||
|
||||
|
||||
# tree
|
||||
日志
|
||||
```
|
||||
----- unicstl test -----
|
||||
|
||||
|
@ -22,13 +22,13 @@ struct _deque_node
|
||||
|
||||
struct _deque
|
||||
{
|
||||
struct _deque_node* _head; // 头节点
|
||||
struct _deque_node* _tail; // 尾节点
|
||||
struct _deque_node* _head;
|
||||
struct _deque_node* _tail;
|
||||
|
||||
uint32_t _obj_size; // 元素大小
|
||||
uint32_t _size; // 栈大小
|
||||
// uint32_t _capacity; // 总容量
|
||||
// uint32_t _ratio; // 扩展比率
|
||||
uint32_t _obj_size;
|
||||
uint32_t _size;
|
||||
// uint32_t _capacity;
|
||||
// uint32_t _ratio;
|
||||
|
||||
// kernel
|
||||
bool (*push_back)(struct _deque* self, void* obj);
|
||||
|
@ -17,12 +17,12 @@ struct _heap
|
||||
{
|
||||
void * obj;
|
||||
|
||||
uint32_t _size; // 栈大小
|
||||
uint32_t _obj_size; // 元素大小
|
||||
uint32_t _capacity; // 总容量
|
||||
uint32_t _ratio; // 扩展比率
|
||||
uint32_t _size;
|
||||
uint32_t _obj_size;
|
||||
uint32_t _capacity;
|
||||
uint32_t _ratio;
|
||||
|
||||
bool _min_flag; // 最大/小堆标志
|
||||
bool _min_flag;
|
||||
|
||||
// kernel
|
||||
bool (*peek)(struct _heap* self, void* obj);
|
||||
|
@ -17,21 +17,27 @@ struct _list
|
||||
{
|
||||
void * obj;
|
||||
|
||||
uint32_t _obj_size; // 元素大小
|
||||
uint32_t _size; // 栈大小
|
||||
uint32_t _capacity; // 总容量
|
||||
uint32_t _ratio; // 扩展比率
|
||||
uint32_t _obj_size;
|
||||
uint32_t _size;
|
||||
uint32_t _capacity;
|
||||
uint32_t _ratio;
|
||||
uint32_t _cur;
|
||||
|
||||
// kernel
|
||||
bool (*append)(struct _list* self, void* obj); // Append object to the end of the list.
|
||||
bool (*insert)(struct _list* self, int index, void* obj); // Insert object before index.
|
||||
bool (*pop)(struct _list* self, int index, void* obj); // Remove and return item at index.
|
||||
bool (*append)(struct _list* self, void* obj); // Append object to the end of the list.
|
||||
bool (*insert)(struct _list* self, int index, void* obj); // Insert object before index.
|
||||
bool (*pop)(struct _list* self, int index, void* obj); // Remove and return item at index.
|
||||
|
||||
int (*index)(struct _list* self, void* obj); // Return first index of obj. Return -1 if the obj is not present.
|
||||
bool (*remove)(struct _list* self, void *obj); // Remove first occurrence of obj.
|
||||
int (*index)(struct _list* self, void* obj); // Return first index of obj. Return -1 if the obj is not present.
|
||||
bool (*remove)(struct _list* self, void *obj); // Remove first occurrence of obj.
|
||||
|
||||
bool (*get)(struct _list* self, int index, void* obj); // 根据索引,获取对象
|
||||
bool (*set)(struct _list* self, int index, void* obj); // 根据索引,修改对象
|
||||
bool (*get)(struct _list* self, int index, void* obj);
|
||||
bool (*set)(struct _list* self, int index, void* obj);
|
||||
|
||||
// iter
|
||||
void* (*begin)(struct _list* self);
|
||||
void* (*next)(struct _list* self);
|
||||
void* (*end)(struct _list* self);
|
||||
|
||||
// base
|
||||
uint32_t(*size)(struct _list* self);
|
||||
@ -43,7 +49,7 @@ struct _list
|
||||
|
||||
|
||||
// sort
|
||||
bool (*reverse)(struct _list* self); // Reverse *IN PLACE*.
|
||||
bool (*reverse)(struct _list* self); // Reverse *IN PLACE*.
|
||||
|
||||
/**
|
||||
Sort the list in ascending order and return false.
|
||||
|
@ -27,10 +27,10 @@ struct _queue
|
||||
uint32_t _index_front;
|
||||
uint32_t _index_back;
|
||||
|
||||
uint32_t _obj_size; // 元素大小
|
||||
uint32_t _size; // 栈大小
|
||||
uint32_t _capacity; // 总容量
|
||||
uint32_t _ratio; // 扩展比率
|
||||
uint32_t _obj_size;
|
||||
uint32_t _size;
|
||||
uint32_t _capacity;
|
||||
uint32_t _ratio;
|
||||
|
||||
// kernel
|
||||
bool (*push)(struct _queue* self, void* obj);
|
||||
|
@ -23,19 +23,19 @@ struct _stack
|
||||
{
|
||||
struct _stack_node * _head;
|
||||
|
||||
uint32_t _size; // 栈大小
|
||||
uint32_t _obj_size; // 元素大小
|
||||
uint32_t _capacity; // 总容量
|
||||
uint32_t _ratio; // 扩展比率
|
||||
uint32_t _size;
|
||||
uint32_t _obj_size;
|
||||
uint32_t _capacity;
|
||||
uint32_t _ratio;
|
||||
|
||||
// kernel
|
||||
bool (*peek)(struct _stack* self, void* obj);
|
||||
bool (*push)(struct _stack* self, void* obj);
|
||||
bool (*pop)(struct _stack* self, void* obj);
|
||||
bool (*peek)(struct _stack* self, void* obj);
|
||||
|
||||
// base
|
||||
bool (*empty)(struct _stack* self);
|
||||
uint32_t (*size)(struct _stack* self);
|
||||
bool (*empty)(struct _stack* self);
|
||||
uint32_t (*capacity)(struct _stack* self);
|
||||
|
||||
// clear and free node
|
||||
|
@ -36,12 +36,12 @@ struct _tree
|
||||
{
|
||||
struct _tree_node * _root;
|
||||
|
||||
uint32_t _size; // 栈大小
|
||||
uint32_t _obj_size; // 元素大小
|
||||
uint32_t _capacity; // 总容量
|
||||
uint32_t _ratio; // 扩展比率
|
||||
uint32_t _size;
|
||||
uint32_t _obj_size;
|
||||
uint32_t _capacity;
|
||||
uint32_t _ratio;
|
||||
|
||||
bool _right_priority; // 右优先
|
||||
bool _right_priority;
|
||||
|
||||
// kernel
|
||||
bool (*insert)(struct _tree* self, void* obj);
|
||||
|
@ -76,7 +76,7 @@ static void heap_fixed_up(struct _heap* self, int i)
|
||||
while(1)
|
||||
{
|
||||
p = parent(i);
|
||||
// 若当前节点大于其父节点,则交换位置,否则退出循环
|
||||
// if current node is greater than its parent, swap the position. otherwise break out of loop
|
||||
if(p < 0 || self->compare((char *)self->obj + i * self->_obj_size, (char *)self->obj + p * self->_obj_size) <= 0)
|
||||
{
|
||||
break;
|
||||
@ -90,7 +90,7 @@ static void heap_fixed_up(struct _heap* self, int i)
|
||||
while(1)
|
||||
{
|
||||
p = parent(i);
|
||||
// 若当前节点大于其父节点,则交换位置,否则退出循环
|
||||
// if current node is less than its parent, swap the position. otherwise break out of loop
|
||||
if(p < 0 || self->compare((char *)self->obj + i * self->_obj_size, (char *)self->obj + p * self->_obj_size) >= 0)
|
||||
{
|
||||
break;
|
||||
|
35
src/list.c
35
src/list.c
@ -61,7 +61,7 @@ bool list_insert(struct _list* self, int index, void* obj)
|
||||
bool list_pop(struct _list* self, int index, void* obj)
|
||||
{
|
||||
assert(self != NULL);
|
||||
assert(index >= (int)(0 - self->size(self)) && index < (int)self->size(self)); // list空的时候也会报错,太严格了有点
|
||||
assert(index >= (int)(0 - self->size(self)) && index < (int)self->size(self));
|
||||
|
||||
if (self->empty(self))
|
||||
{
|
||||
@ -179,6 +179,29 @@ void list_print(struct _list* self)
|
||||
}
|
||||
}
|
||||
|
||||
void* list_begin(struct _list* self)
|
||||
{
|
||||
self->_cur = 0;
|
||||
return self->obj;
|
||||
}
|
||||
|
||||
void* list_end(struct _list* self)
|
||||
{
|
||||
return (char*)self->obj + self->_size * self->_obj_size;
|
||||
}
|
||||
|
||||
void* list_next(struct _list* self)
|
||||
{
|
||||
void *obj = NULL;
|
||||
// if add this, can't go to end
|
||||
// if(self->_cur < self->_size - 1)
|
||||
{
|
||||
self->_cur += 1;
|
||||
}
|
||||
obj = (char*)self->obj + self->_cur * self->_obj_size;
|
||||
return obj;
|
||||
}
|
||||
|
||||
bool list_init2(struct _list* list, uint32_t obj_size, uint32_t capacity)
|
||||
{
|
||||
assert(list != NULL);
|
||||
@ -194,6 +217,7 @@ bool list_init2(struct _list* list, uint32_t obj_size, uint32_t capacity)
|
||||
list->_size = 0;
|
||||
list->_capacity = capacity;
|
||||
list->_ratio = 2;
|
||||
list->_cur = 0;
|
||||
|
||||
// 2. set function
|
||||
// kernel
|
||||
@ -212,8 +236,13 @@ bool list_init2(struct _list* list, uint32_t obj_size, uint32_t capacity)
|
||||
list->size = list_size;
|
||||
list->sort = list_sort;
|
||||
|
||||
list->begin = list_begin;
|
||||
list->next = list_next;
|
||||
list->end = list_end;
|
||||
|
||||
// 3. set array
|
||||
list->obj = (void*)calloc(list->_capacity, list->_obj_size);
|
||||
// list->obj = (void*)calloc(list->_capacity, list->_obj_size);
|
||||
list->obj = (void*)malloc(list->_capacity * list->_obj_size);
|
||||
if (list->obj == NULL)
|
||||
{
|
||||
return false;
|
||||
@ -223,7 +252,7 @@ bool list_init2(struct _list* list, uint32_t obj_size, uint32_t capacity)
|
||||
|
||||
list_t list_new(void)
|
||||
{
|
||||
return (struct _list*)malloc(sizeof(struct _list));
|
||||
return (struct _list*)calloc(1, sizeof(struct _list));
|
||||
}
|
||||
|
||||
void list_free(list_t* list)
|
||||
|
187
src/stack.c
187
src/stack.c
@ -10,22 +10,80 @@
|
||||
*/
|
||||
#include "stack.h"
|
||||
|
||||
static uint32_t stack_capacity(struct _stack* self)
|
||||
static struct _stack_node* stack_node_new(void *obj, uint32_t obj_size)
|
||||
{
|
||||
assert(self != NULL);
|
||||
return self->_capacity;
|
||||
void* new_obj = (void*)calloc(1, obj_size);
|
||||
if (new_obj == NULL)
|
||||
{
|
||||
goto done;
|
||||
}
|
||||
memmove(new_obj, obj, obj_size);
|
||||
|
||||
struct _stack_node* new_node = (struct _stack_node*)malloc(sizeof(struct _stack_node));
|
||||
if (new_node == NULL)
|
||||
{
|
||||
goto done1;
|
||||
}
|
||||
new_node->obj = new_obj;
|
||||
new_node->next = NULL;
|
||||
|
||||
return new_node;
|
||||
done1:
|
||||
free(new_obj);
|
||||
done:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static uint32_t stack_size(struct _stack* self)
|
||||
static void stack_node_free(struct _stack_node** node)
|
||||
{
|
||||
assert(self != NULL);
|
||||
return self->_size;
|
||||
if(node != NULL && *node != NULL)
|
||||
{
|
||||
if((*node)->obj != NULL)
|
||||
{
|
||||
free((*node)->obj);
|
||||
}
|
||||
free(*node);
|
||||
*node = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static bool stack_empty(struct _stack* self)
|
||||
static bool stack_push(struct _stack* self, void* obj)
|
||||
{
|
||||
assert(self != NULL);
|
||||
return stack_size(self) == 0;
|
||||
assert(self->_head != NULL);
|
||||
assert(obj != NULL);
|
||||
|
||||
struct _stack_node* new_node = stack_node_new(obj, self->_obj_size);
|
||||
if (new_node == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
new_node->next = self->_head->next;
|
||||
self->_head->next = new_node;
|
||||
|
||||
self->_size += 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool stack_pop(struct _stack* self, void* obj)
|
||||
{
|
||||
assert(self != NULL);
|
||||
assert(self->_head != NULL);
|
||||
if (self->empty(self))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
struct _stack_node* node = self->_head->next;
|
||||
|
||||
if (obj != NULL)
|
||||
{
|
||||
memmove(obj, node->obj, self->_obj_size);
|
||||
}
|
||||
self->_head->next = node->next;
|
||||
|
||||
stack_node_free(&node);
|
||||
self->_size -= 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool stack_peek(struct _stack* self, void* obj)
|
||||
@ -44,60 +102,23 @@ static bool stack_peek(struct _stack* self, void* obj)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool stack_push(struct _stack* self, void* obj)
|
||||
static uint32_t stack_size(struct _stack* self)
|
||||
{
|
||||
assert(self != NULL);
|
||||
assert(self->_head != NULL);
|
||||
assert(obj != NULL);
|
||||
|
||||
void* new_obj = (void*)calloc(1, self->_obj_size);
|
||||
if (new_obj == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
memmove(new_obj, obj, self->_obj_size);
|
||||
|
||||
struct _stack_node* new_node = (struct _stack_node*)malloc(sizeof(struct _stack_node));
|
||||
if (new_node == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
new_node->obj = new_obj;
|
||||
new_node->next = self->_head->next;
|
||||
self->_head->next = new_node;
|
||||
|
||||
self->_size += 1;
|
||||
return true;
|
||||
return self->_size;
|
||||
}
|
||||
|
||||
static bool stack_pop(struct _stack* self, void* obj)
|
||||
static bool stack_empty(struct _stack* self)
|
||||
{
|
||||
assert(self != NULL);
|
||||
assert(self->_head != NULL);
|
||||
// assert(obj != NULL);
|
||||
|
||||
if (self->empty(self))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
assert(self->size != NULL);
|
||||
return self->size(self) == 0;
|
||||
}
|
||||
|
||||
struct _stack_node* node = self->_head->next;
|
||||
|
||||
if (obj != NULL)
|
||||
{
|
||||
// 将弹出的数据输出
|
||||
memmove(obj, node->obj, self->_obj_size);
|
||||
}
|
||||
|
||||
// 更新指针
|
||||
self->_head->next = node->next;
|
||||
|
||||
// 释放数据和节点
|
||||
free(node->obj);
|
||||
free(node);
|
||||
|
||||
self->_size -= 1;
|
||||
return true;
|
||||
static uint32_t stack_capacity(struct _stack* self)
|
||||
{
|
||||
assert(self != NULL);
|
||||
return self->_capacity;
|
||||
}
|
||||
|
||||
static bool stack_clear(struct _stack* self)
|
||||
@ -111,13 +132,8 @@ static bool stack_clear(struct _stack* self)
|
||||
struct _stack_node* node = self->_head->next;
|
||||
while (node != NULL)
|
||||
{
|
||||
// 更新指针
|
||||
self->_head->next = node->next;
|
||||
|
||||
// 释放数据和节点
|
||||
free(node->obj);
|
||||
free(node);
|
||||
|
||||
stack_node_free(&node);
|
||||
node = self->_head->next;
|
||||
}
|
||||
self->_size = 0;
|
||||
@ -146,23 +162,6 @@ static void stack_print(struct _stack* self)
|
||||
}
|
||||
}
|
||||
|
||||
static bool stack2_peek(struct _stack* self, void* obj)
|
||||
{
|
||||
assert(self != NULL);
|
||||
assert(self->_head != NULL);
|
||||
assert(obj != NULL);
|
||||
|
||||
if (self->empty(self))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t top = self->size(self) - 1;
|
||||
uint32_t offset = top * self->_obj_size;
|
||||
memmove(obj, (char *)self->_head->obj + offset, self->_obj_size);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool stack2_push(struct _stack* self, void* obj)
|
||||
{
|
||||
assert(self != NULL);
|
||||
@ -191,8 +190,6 @@ static bool stack2_pop(struct _stack* self, void* obj)
|
||||
{
|
||||
assert(self != NULL);
|
||||
assert(self->_head != NULL);
|
||||
// assert(obj != NULL);
|
||||
|
||||
if (self->empty(self))
|
||||
{
|
||||
return false;
|
||||
@ -204,11 +201,25 @@ static bool stack2_pop(struct _stack* self, void* obj)
|
||||
uint32_t offset = top * self->_obj_size;
|
||||
memmove(obj, (char*)self->_head->obj + offset, self->_obj_size);
|
||||
}
|
||||
|
||||
self->_size -= 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool stack2_peek(struct _stack* self, void* obj)
|
||||
{
|
||||
assert(self != NULL);
|
||||
assert(self->_head != NULL);
|
||||
assert(obj != NULL);
|
||||
if (self->empty(self))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t top = self->size(self) - 1;
|
||||
uint32_t offset = top * self->_obj_size;
|
||||
memmove(obj, (char *)self->_head->obj + offset, self->_obj_size);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void stack2_destory(struct _stack* self)
|
||||
{
|
||||
@ -260,13 +271,13 @@ bool stack_init(struct _stack* self, uint32_t obj_size)
|
||||
|
||||
// 2. set function
|
||||
// kernel
|
||||
self->peek = stack_peek;
|
||||
self->pop = stack_pop;
|
||||
self->push = stack_push;
|
||||
self->pop = stack_pop;
|
||||
self->peek = stack_peek;
|
||||
|
||||
// base
|
||||
self->empty = stack_empty;
|
||||
self->size = stack_size;
|
||||
self->empty = stack_empty;
|
||||
self->capacity = stack_capacity;
|
||||
|
||||
// clear and free node
|
||||
@ -299,10 +310,10 @@ bool stack_init2(struct _stack* self, uint32_t obj_size, uint32_t capacity)
|
||||
|
||||
// 2. set function
|
||||
// kernel
|
||||
self->peek = stack2_peek;
|
||||
self->pop = stack2_pop;
|
||||
self->push = stack2_push;
|
||||
|
||||
self->pop = stack2_pop;
|
||||
self->peek = stack2_peek;
|
||||
|
||||
// others
|
||||
self->empty = stack_empty;
|
||||
self->size = stack_size;
|
||||
@ -321,7 +332,7 @@ bool stack_init2(struct _stack* self, uint32_t obj_size, uint32_t capacity)
|
||||
return false;
|
||||
}
|
||||
// self->_head->obj = NULL;
|
||||
self->_head->next = NULL; // 无效参数
|
||||
self->_head->next = NULL;
|
||||
|
||||
// 4. set array
|
||||
self->_head->obj = (void *)calloc(self->_capacity, self->_obj_size);
|
||||
|
46
src/tree.c
46
src/tree.c
@ -185,14 +185,14 @@ int32_t tree_height(struct _tree* self, struct _tree_node* root)
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* 以 balance = rigth - left 为标准,调整平衡因子
|
||||
* if balance = rigth - left,so
|
||||
*
|
||||
* | 情况 | root->balance | node->balance | 调整方式 |
|
||||
* | case | root->balance | node->balance | function |
|
||||
* | ---- | ------------ | -------------- | -------- |
|
||||
* | 1 | 2 | >= 0 | 左旋
|
||||
* | 2 | 2 | < 0 | 先右旋后左旋
|
||||
* | 3 | -2 | <= 0 | 右旋
|
||||
* | 4 | -2 | > 0 | 先左旋后右旋
|
||||
* | 1 | 2 | >= 0 | left rotation
|
||||
* | 2 | 2 | < 0 | first right rotation, then left rotation
|
||||
* | 3 | -2 | <= 0 | right rotation
|
||||
* | 4 | -2 | > 0 | forth left rotation, then right rotation
|
||||
*
|
||||
* @param self
|
||||
* @return true
|
||||
@ -347,10 +347,10 @@ static bool tree_node_free(struct _tree_node* node)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 在树中查找插入位置
|
||||
* @brief find the position to insert or find object
|
||||
*
|
||||
* @param self 树的指针
|
||||
* @param obj 要查找或插入的对象
|
||||
* @param self
|
||||
* @param obj
|
||||
*/
|
||||
struct _tree_node * tree_find_pos(struct _tree* self, void* obj)
|
||||
{
|
||||
@ -1185,14 +1185,14 @@ bool tree_rb_insert(struct _tree* self, void* obj)
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* 以 balance = rigth - left 为标准,调整平衡因子
|
||||
* 以 balance = rigth - left 为标准,调整平衡因子
|
||||
*
|
||||
* | 情况 | root->balance | node->balance | 调整方式 |
|
||||
* | 情况 | root->balance | node->balance | 调整方式 |
|
||||
* | ---- | ------------ | -------------- | -------- |
|
||||
* | 1 | 2 | >= 0 | 左旋
|
||||
* | 2 | 2 | < 0 | 先右旋后左旋
|
||||
* | 3 | -2 | <= 0 | 右旋
|
||||
* | 4 | -2 | > 0 | 先左旋后右旋
|
||||
* | 1 | 2 | >= 0 | 左旋
|
||||
* | 2 | 2 | < 0 | 先右旋后左旋
|
||||
* | 3 | -2 | <= 0 | 右旋
|
||||
* | 4 | -2 | > 0 | 先左旋后右旋
|
||||
*
|
||||
* @param self
|
||||
* @return true
|
||||
@ -1210,18 +1210,18 @@ static bool tree_rb_rebalance(struct _tree* self, struct _tree_node* node)
|
||||
struct _tree_node* uncle = NULL;
|
||||
|
||||
/**
|
||||
* @brief 新插入节点为红色,且父节点为红色的情况下,需要调整。
|
||||
* @brief 新插入节点为红色,且父节点为红色的情况下,需要调整。
|
||||
*
|
||||
* 主要考虑前三种情况[1-3],其余三种[4-6]对称操作即可
|
||||
* 主要考虑前三种情况[1-3],其余三种[4-6]对称操作即可
|
||||
*
|
||||
* 原则只有一个,那就是想办法维持红黑树性质不变
|
||||
* 原则只有一个,那就是想办法维持红黑树性质不变
|
||||
*
|
||||
* | 情况 | 说明 | 调整方式 |
|
||||
* | 情况 | 说明 | 调整方式 |
|
||||
* | ---- | --- | -------- |
|
||||
* | 0 | 父节点为黑色 | 不用处理
|
||||
* | 1 | 父红,爷黑,叔红 | 仅变色即可:父黑,爷红,叔黑
|
||||
* | 2 | 父红,爷黑,叔黑 | (若爷孙在同一边)父黑,爷红,爷左/右旋
|
||||
* | 3 | 父红,爷黑,叔黑 | (若爷孙在不同边)先父左右旋,将新父变黑,随后爷红,爷左/右旋
|
||||
* | 0 | 父节点为黑色 | 不用处理
|
||||
* | 1 | 父红,爷黑,叔红 | 仅变色即可:父黑,爷红,叔黑
|
||||
* | 2 | 父红,爷黑,叔黑 | (若爷孙在同一边)父黑,爷红,爷左/右旋
|
||||
* | 3 | 父红,爷黑,叔黑 | (若爷孙在不同边)先父左右旋,将新父变黑,随后爷红,爷左/右旋
|
||||
*/
|
||||
while(node->parent != NULL && node->parent->color == RBT_RED)
|
||||
{
|
||||
|
@ -56,7 +56,7 @@ void print_str(void* obj)
|
||||
|
||||
|
||||
// --------------------------------------------------
|
||||
// 测试用例
|
||||
// 测试用例
|
||||
// --------------------------------------------------
|
||||
void setUp(void)
|
||||
{
|
||||
|
268
test/test_list.c
268
test/test_list.c
@ -45,9 +45,8 @@ static void test_list_new(void)
|
||||
list_free(&list); // list_free(NULL);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
static void test_list_push(void)
|
||||
static void test_list_append(void)
|
||||
{
|
||||
int temp = 0;
|
||||
int data[] = { 1,2,3,4,5,6,7,8,9,10 };
|
||||
@ -56,32 +55,16 @@ static void test_list_push(void)
|
||||
|
||||
list_t list = NULL;
|
||||
|
||||
// ------------------------------
|
||||
list = list_new();
|
||||
list_init2(list, sizeof(int));
|
||||
TEST_ASSERT_TRUE(list->empty(list));
|
||||
for(i = 0; i < len; i++)
|
||||
{
|
||||
TEST_ASSERT_TRUE(list->push(list, &data[i]));
|
||||
TEST_ASSERT_EQUAL_INT(i + 1, list->size(list));
|
||||
|
||||
TEST_ASSERT_TRUE(list->peek(list, &temp));
|
||||
TEST_ASSERT_EQUAL_INT(data[i], temp);
|
||||
|
||||
TEST_ASSERT_FALSE(list->empty(list));
|
||||
}
|
||||
list_free(&list);
|
||||
|
||||
// ------------------------------
|
||||
list = list_new();
|
||||
list_init2(list, sizeof(int), len);
|
||||
TEST_ASSERT_TRUE(list->empty(list));
|
||||
for(i = 0; i < len; i++)
|
||||
{
|
||||
TEST_ASSERT_TRUE(list->push(list, &data[i]));
|
||||
TEST_ASSERT_TRUE(list->append(list, &data[i]));
|
||||
TEST_ASSERT_EQUAL_INT(i + 1, list->size(list));
|
||||
|
||||
TEST_ASSERT_TRUE(list->peek(list, &temp));
|
||||
TEST_ASSERT_TRUE(list->get(list, i, &temp));
|
||||
TEST_ASSERT_EQUAL_INT(data[i], temp);
|
||||
|
||||
TEST_ASSERT_FALSE(list->empty(list));
|
||||
@ -94,12 +77,13 @@ static void test_list_push(void)
|
||||
list_init2(list, sizeof(int), len - 2);
|
||||
for(i = 0; i < len; i++)
|
||||
{
|
||||
TEST_ASSERT_TRUE(list->push(list, &data[i]));
|
||||
TEST_ASSERT_TRUE(list->append(list, &data[i]));
|
||||
TEST_ASSERT_EQUAL_INT(i + 1, list->size(list));
|
||||
}
|
||||
list_free(&list);
|
||||
}
|
||||
|
||||
|
||||
static void test_list_pop(void)
|
||||
{
|
||||
int temp = 0;
|
||||
@ -109,97 +93,23 @@ static void test_list_pop(void)
|
||||
|
||||
list_t list = NULL;
|
||||
|
||||
// ------------------------------
|
||||
list = list_new();
|
||||
list_init2(list, sizeof(int));
|
||||
for(i = 0; i < len; i++)
|
||||
{
|
||||
list->push(list, &data[i]);
|
||||
}
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
TEST_ASSERT_TRUE(list->peek(list, &temp));
|
||||
TEST_ASSERT_EQUAL_INT(data[list->size(list) - 1], temp);
|
||||
|
||||
TEST_ASSERT_TRUE(list->pop(list, &temp));
|
||||
|
||||
if (!list->empty(list))
|
||||
{
|
||||
TEST_ASSERT_TRUE(list->peek(list, &temp));
|
||||
TEST_ASSERT_EQUAL_INT(data[list->size(list) - 1], temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
TEST_ASSERT_FALSE(list->peek(list, &temp));
|
||||
}
|
||||
}
|
||||
TEST_ASSERT_TRUE(list->empty(list));
|
||||
TEST_ASSERT_FALSE(list->pop(list, &temp));
|
||||
list_free(&list);
|
||||
|
||||
// ------------------------------
|
||||
list = list_new();
|
||||
list_init2(list, sizeof(int), len);
|
||||
for(i = 0; i < len; i++)
|
||||
{
|
||||
list->push(list, &data[i]);
|
||||
list->append(list, &data[i]);
|
||||
}
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
TEST_ASSERT_TRUE(list->peek(list, &temp));
|
||||
TEST_ASSERT_EQUAL_INT(data[list->size(list) - 1], temp);
|
||||
|
||||
TEST_ASSERT_TRUE(list->pop(list, &temp));
|
||||
|
||||
if (!list->empty(list))
|
||||
{
|
||||
TEST_ASSERT_TRUE(list->peek(list, &temp));
|
||||
TEST_ASSERT_EQUAL_INT(data[list->size(list) - 1], temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
TEST_ASSERT_FALSE(list->peek(list, &temp));
|
||||
}
|
||||
TEST_ASSERT_TRUE(list->pop(list, 0, &temp));
|
||||
}
|
||||
TEST_ASSERT_TRUE(list->empty(list));
|
||||
TEST_ASSERT_FALSE(list->pop(list, &temp));
|
||||
list_free(&list);
|
||||
|
||||
// ------------------------------
|
||||
// if capacity is less than data len
|
||||
list = list_new();
|
||||
list_init2(list, sizeof(int), len - 2);
|
||||
for(i = 0; i < len; i++)
|
||||
{
|
||||
TEST_ASSERT_TRUE(list->push(list, &data[i]));
|
||||
TEST_ASSERT_EQUAL_INT(i + 1, list->size(list));
|
||||
}
|
||||
uint32_t capacity = list->capacity(list);
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
if (!list->empty(list))
|
||||
{
|
||||
TEST_ASSERT_TRUE(list->pop(list, &temp));
|
||||
}
|
||||
else
|
||||
{
|
||||
TEST_ASSERT_FALSE(list->pop(list, &temp));
|
||||
}
|
||||
|
||||
if (!list->empty(list))
|
||||
{
|
||||
TEST_ASSERT_TRUE(list->peek(list, &temp));
|
||||
TEST_ASSERT_EQUAL_INT(data[list->size(list) - 1], temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
TEST_ASSERT_FALSE(list->pop(list, &temp));
|
||||
TEST_ASSERT_FALSE(list->peek(list, &temp));
|
||||
}
|
||||
}
|
||||
// TEST_ASSERT_FALSE(list->pop(list, 1, &temp));
|
||||
list_free(&list);
|
||||
}
|
||||
|
||||
|
||||
static void test_list_clear(void)
|
||||
{
|
||||
int temp = 0;
|
||||
@ -209,31 +119,13 @@ static void test_list_clear(void)
|
||||
|
||||
list_t list = NULL;
|
||||
|
||||
// ------------------------------
|
||||
list = list_new();
|
||||
list_init2(list, sizeof(int));
|
||||
for(i = 0; i < len; i++)
|
||||
{
|
||||
list->push(list, &data[i]);
|
||||
}
|
||||
TEST_ASSERT_TRUE(list->clear(list));
|
||||
for(i = 0; i < len; i++)
|
||||
{
|
||||
list->push(list, &data[i]);
|
||||
}
|
||||
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);
|
||||
|
||||
// ------------------------------
|
||||
list = list_new();
|
||||
list_init2(list, sizeof(int), len);
|
||||
TEST_ASSERT_TRUE(list->clear(list));
|
||||
for(i = 0; i < len; i++)
|
||||
{
|
||||
list->push(list, &data[i]);
|
||||
list->append(list, &data[i]);
|
||||
}
|
||||
TEST_ASSERT_FALSE(list->empty(list));
|
||||
TEST_ASSERT_TRUE(list->clear(list));
|
||||
@ -244,57 +136,89 @@ static void test_list_clear(void)
|
||||
|
||||
static void test_list_num(void)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
int i = 0;
|
||||
int data[] = { 1,2,3,4,5,6,7,8,9,10 };
|
||||
int temp = 0;
|
||||
uint32_t len = sizeof(data) / sizeof(data[0]);
|
||||
int index = 0;
|
||||
int len = sizeof(data) / sizeof(data[0]);
|
||||
|
||||
list_t list = NULL;
|
||||
list = list_new();
|
||||
TEST_ASSERT_NOT_NULL(list);
|
||||
TEST_ASSERT_TRUE(list != NULL);
|
||||
|
||||
TEST_ASSERT_TRUE(list_init2(list, sizeof(int)));
|
||||
list_init2(list, sizeof(int), 64);
|
||||
list->print_obj = print_num;
|
||||
|
||||
TEST_ASSERT_FALSE(list->peek(list, &temp));
|
||||
TEST_ASSERT_TRUE(list->clear(list));
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
TEST_ASSERT_TRUE(list->push(list, &data[i]));
|
||||
TEST_ASSERT_EQUAL_INT(i + 1, list->size(list));
|
||||
|
||||
TEST_ASSERT_TRUE(list->peek(list, &temp));
|
||||
TEST_ASSERT_EQUAL_INT(data[i], temp);
|
||||
TEST_ASSERT_TRUE(list->append(list, &data[i]));
|
||||
}
|
||||
|
||||
TEST_ASSERT_FALSE(list->empty(list));
|
||||
TEST_ASSERT_TRUE(list->pop(list, 9, NULL));
|
||||
TEST_ASSERT_TRUE(list->pop(list, 0, NULL));
|
||||
TEST_ASSERT_TRUE(list->pop(list, 4, NULL));
|
||||
TEST_ASSERT_TRUE(list->clear(list));
|
||||
TEST_ASSERT_TRUE(list->empty(list));
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
TEST_ASSERT_TRUE(list->push(list, &data[i]));
|
||||
TEST_ASSERT_TRUE(list->append(list, &data[i]));
|
||||
}
|
||||
index = 0;
|
||||
TEST_ASSERT_TRUE(list->get(list, index, &temp));
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
index = 4;
|
||||
TEST_ASSERT_TRUE(list->get(list, index, &temp));
|
||||
|
||||
index = 9;
|
||||
TEST_ASSERT_TRUE(list->get(list, index, &temp));
|
||||
|
||||
index = 0;
|
||||
temp = 11;
|
||||
TEST_ASSERT_TRUE(list->set(list, index, &temp));
|
||||
|
||||
index = 4;
|
||||
temp = 22;
|
||||
TEST_ASSERT_TRUE(list->set(list, index, &temp));
|
||||
|
||||
index = 9;
|
||||
temp = 33;
|
||||
TEST_ASSERT_TRUE(list->set(list, index, &temp));
|
||||
|
||||
index = -1;
|
||||
TEST_ASSERT_TRUE(list->get(list, index, &temp));
|
||||
|
||||
index = -6;
|
||||
TEST_ASSERT_TRUE(list->get(list, index, &temp));
|
||||
|
||||
index = -10;
|
||||
TEST_ASSERT_TRUE(list->get(list, index, &temp));
|
||||
|
||||
index = -1;
|
||||
temp = 99;
|
||||
TEST_ASSERT_TRUE(list->set(list, index, &temp));
|
||||
|
||||
index = -6;
|
||||
temp = 98;
|
||||
TEST_ASSERT_TRUE(list->set(list, index, &temp));
|
||||
|
||||
index = -10;
|
||||
temp = 97;
|
||||
TEST_ASSERT_TRUE(list->set(list, index, &temp));
|
||||
|
||||
for (i = 0; i < len + 1; i++)
|
||||
{
|
||||
TEST_ASSERT_TRUE(list->peek(list, &temp));
|
||||
TEST_ASSERT_EQUAL_INT(data[list->size(list) - 1], temp);
|
||||
TEST_ASSERT_TRUE(list->pop(list, 0, &temp));
|
||||
|
||||
TEST_ASSERT_TRUE(list->pop(list, &temp));
|
||||
|
||||
if (!list->empty(list))
|
||||
if (list->empty(list))
|
||||
{
|
||||
TEST_ASSERT_TRUE(list->peek(list, &temp));
|
||||
TEST_ASSERT_EQUAL_INT(data[list->size(list) - 1], temp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
TEST_ASSERT_TRUE(list->empty(list));
|
||||
TEST_ASSERT_FALSE(list->pop(list, &temp));
|
||||
|
||||
list_free(&list);
|
||||
TEST_ASSERT_NULL(list);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void test_list_struct(void)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
@ -471,20 +395,64 @@ static void test_list2_struct(void)
|
||||
list_free(&list);
|
||||
TEST_ASSERT_NULL(list);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
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_new();
|
||||
list_init2(list, 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);
|
||||
}
|
||||
|
||||
void test_list(void)
|
||||
{
|
||||
RUN_TEST(test_list_init2);
|
||||
RUN_TEST(test_list_new);
|
||||
// RUN_TEST(test_list_push);
|
||||
// RUN_TEST(test_list_pop);
|
||||
// RUN_TEST(test_list_clear);
|
||||
RUN_TEST(test_list_append);
|
||||
RUN_TEST(test_list_pop);
|
||||
RUN_TEST(test_list_clear);
|
||||
|
||||
// RUN_TEST(test_list_num);
|
||||
RUN_TEST(test_list_num);
|
||||
// RUN_TEST(test_list_struct);
|
||||
|
||||
// RUN_TEST(test_list2_num);
|
||||
// RUN_TEST(test_list2_struct);
|
||||
RUN_TEST(test_list_iter);
|
||||
}
|
||||
|
@ -10,10 +10,6 @@
|
||||
*/
|
||||
#include "test.h"
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* 每成功init一次,就需要对应的destory一次。否则可能存在内存泄漏
|
||||
*/
|
||||
static void test_queue_init(void)
|
||||
{
|
||||
struct _queue queue;
|
||||
@ -36,10 +32,6 @@ static void test_queue_init(void)
|
||||
queue.destory(&queue);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* 每成功init一次,就需要对应的free一次。否则可能存在内存泄漏
|
||||
*/
|
||||
static void test_queue_new(void)
|
||||
{
|
||||
queue_t queue = NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user