Vector组件--它是类似于链表拥有的能力,是一种动态数组存储组件,Vector组件拥有的能力如下:
接口 | 描述 |
---|---|
Vector VECTOR_Make(VECTOR_Key key, VECTOR_Compare compare) | 创建Vector列表对象,用户根据业务注册VECTOR_Key方法和VECTOR_Compare方法 |
void VECTOR_Clear(Vector *vector) | 清空Vector列表对象,并释放存储数据空间 |
int16_t VECTOR_Add(Vector *vector, void *element) | 添加元素到Vector列表对象 |
int16_t VECTOR_Size(Vector *vector) | 获取Vector列表对象的元素个数 |
int16_t VECTOR_Num(Vector *vector) | 获取Vector列表对象的元素记录数目 |
void *VECTOR_At(Vector *vector, int16_t index) | 根据下标获取Vector列表对象的元素 |
void *VECTOR_Swap(Vector *vector, int16_t index, void *element) | 替换指定下标的Vector列表对象的元素 |
int16_t VECTOR_Find(Vector *vector, const void *element) | 通过元素从Vector列表对象中查找对应下标 |
int16_t VECTOR_FindByKey(Vector *vector, const void *key) | 通过键从Vector列表对象中查找对应下标 |
// vector.h
#define GROW_STEP 4
#define INVALID_INDEX (-1)
typedef void *(*VECTOR_Key)(const void *); // 应用层提供KEY-VALUE获取方法,泛类型
typedef int (*VECTOR_Compare)(const void *, const void *); // 应用层提供比较函数,泛类型
typedef struct SimpleVector {
int16_t max; // vector所能存储的最大数据记录数目
int16_t top; // vector当前已经存储的数据的峰值数目
int16_t free; // vector已经被释放的数据记录数目
void **data; // vector存储数据指针
VECTOR_Key key; // 将数据元素转换为用于比较的键。方法由用户提供
VECTOR_Compare compare; // 将用于比较键值。方法由用户提供
} Vector;
Vector VECTOR_Make(VECTOR_Key key, VECTOR_Compare compare)
{
Vector vector = {0, 0, 0, NULL, key, compare};
return vector;
}
void VECTOR_Clear(Vector *vector)
{
if (vector == NULL) {
return;
}
if (vector->data == NULL) {
return;
}
free(vector->data);
vector->max = 0;
vector->top = 0;
vector->free = 0;
vector->data = NULL;
}
int16_t VECTOR_Add(Vector *vector, void *element)
{
if (vector == NULL || element == NULL) {
return INVALID_INDEX;
}
if (vector->top >= vector->max) {
int16_t i;
for (i = vector->top - (int16_t)1; i >= 0; --i) {
if (vector->data[i] == NULL) {
vector->data[i] = element;
vector->free--;
return i;
}
}
if (vector->max + GROW_STEP < 0) {
return INVALID_INDEX;
}
void **data = (void **)malloc(sizeof(void *) * (vector->max + GROW_STEP));
if (data == NULL) {
return INVALID_INDEX;
}
if (vector->data != NULL) {
(void)memcpy(data, vector->data, sizeof(void *) * vector->max);
free(vector->data);
}
vector->data = data;
vector->max += GROW_STEP;
}
vector->data[vector->top] = element;
return vector->top++;
}
void *VECTOR_At(Vector *vector, int16_t index)
{
if (vector == NULL || vector->top <= index || index < 0) {
return NULL;
}
return vector->data[index];
}
void *VECTOR_Swap(Vector *vector, int16_t index, void *element)
{
if (vector == NULL || vector->top <= index || index < 0) {
return NULL;
}
if (element == NULL) {
vector->free++;
}
void *oldElement = vector->data[index];
vector->data[index] = element;
return oldElement;
}
int16_t VECTOR_Find(Vector *vector, const void *element)
{
if (vector == NULL || element == NULL) {
return INVALID_INDEX;
}
return VECTOR_FindByKey(vector, (vector->key == NULL) ? element : vector->key(element));
}
int16_t VECTOR_FindByKey(Vector *vector, const void *key)
{
if (vector == NULL || key == NULL) {
return INVALID_INDEX;
}
int16_t i;
for (i = 0; i < vector->top; ++i) {
if (vector->data[i] == NULL) {
continue;
}
void *first = (vector->key != NULL) ? vector->key(vector->data[i]) : vector->data[i];
if (first == key) {
return i;
}
if (vector->compare == NULL || first == NULL) {
continue;
}
if (vector->compare(first, key) == 0) {
return i;
}
}
return INVALID_INDEX;
}
int16_t VECTOR_Size(Vector *vector)
{
if (vector == NULL) {
return INVALID_INDEX;
}
return vector->top;
}
int16_t VECTOR_Num(Vector *vector)
{
if (vector == NULL) {
return INVALID_INDEX;
}
return vector->top - vector->free;
}
定义一个元素结构体(vector_test),包含两个字段:name和data,其中name可以作为元素对象的唯一标识。
定义两个vector_test变量,test1和test2。
我们这个demo是采用name作为唯一标识,需要顶一个函数用于获取vector_test变量的name字段成员的值,作为VECTOR_Key指向函数。
通过VECTOR_Make构造一个vector对象。其中VECTOR_Key指向vector_name_get函数作为key获取,VECTOR_Compare指向strcmp函数用于key(name字符串)的比较。
通过VECTOR_Add向vector对象增加元素test1和test2。
通过VECTOR_FindByKey从vector对象查找元素对象下标。如:key为"rice"的元素对象下标。
通过VECTOR_FindByKey获取的pos,调用VECTOR_At获取元素对象。
验证:根据获取元素对象调用其成员,确定是否成功。
#include "vector.h"
Vector vector;
typedef struct {
char *name;
int data;
}vector_test;
vector_test test1 = {"rice", 100};
vector_test test2 = {"chen", 100};
const char *vector_name_get(vector_test *test)
{
return test->name;
}
int main(void)
{
vector = VECTOR_Make(vector_name_get, strcmp);
VECTOR_Add(&vector, &test1);
VECTOR_Add(&vector, &test2);
int16_t pos = VECTOR_FindByKey(&vector, "rice");
printf("pos: %drn", pos);
vector_test *temp = VECTOR_At(&vector, pos);
printf("name: %srn", temp->name);
return RT_EOK;
}
欢迎关注微信公众号『Rice嵌入式开发技术分享』
全部0条评论
快来发表一下你的评论吧 !