动态数组,扩充和缩小

 

//首先是数据结构,size记录使用的空间,alloc_size记录分配的空间 data为指针的指针,为了灵活性,必须的。

struct _DArray
{
    size_t size;
    size_t alloc_size;
    void** data;
};
typedef struct _DArray DArray;

 

//一些接口的定义。
DArray* darray_create(DataDestroyFunc data_destroy, void* ctx);

Ret darray_insert(DArray* thiz, size_t index, void* data);
Ret darray_prepend(DArray* thiz, void* data);
Ret darray_append(DArray* thiz, void* data);
Ret darray_delete(DArray* thiz, size_t index);
Ret darray_get_by_index(DArray* thiz, size_t index, void** data);
Ret darray_set_by_index(DArray* thiz, size_t index, void* data);
size_t darray_length(DArray* thiz);
int darray_find(DArray* thiz, DataCompareFunc cmp, void* ctx);
Ret darray_foreach(DArray* thiz, DataVisitFunc visit, void* ctx);

void darray_destroy(DArray* thiz);

 

/*************************************

*     好的到了关键的地方了,在空间不足的时候,动态扩充容量,为了提高效率,

*一次扩充多个空间,在不够用的时候,一次扩充为原来的1.5倍,

*计算公式为alloc_size = thiz->alloc_size + (thiz->alloc_size>>1) + MIN_PRE_ALLOCATE_NR

*这样就可以避免一些环境中没有浮点运算,以及浮点运算可能造成的误差~~最后那个数,是为了防止到了一定时候,分配过于频繁

*

*

********************************************/
#define MIN_PRE_ALLOCATE_NR 10
static Ret darray_expand(DArray* thiz, size_t need)
{
    return_val_if_fail(thiz != NULL, RET_INVALID_PARAMS);

    if((thiz->size + need) > thiz->alloc_size)
    {
        size_t alloc_size = thiz->alloc_size + (thiz->alloc_size>>1) + MIN_PRE_ALLOCATE_NR ;
        void** data = (void **)realloc(thiz->data,sizeof(void*) * alloc_size);
        if(data != NULL)
        {
            thiz->data = data;
            thiz->alloc_size = alloc_size;
        }
    }
    return ((thiz->size + need) <= thiz->alloc_size) ? RET_OK : RET_FAIL;
}

 

 

//插入函数,在某个下标插入,最多也就在当前数组的末尾,会自动调整。
Ret darray_insert(DArray* thiz, size_t index, void* data)
{
    Ret ret = RET_OOM;
    size_t cursor = index;
    return_val_if_fail(thiz != NULL, RET_INVALID_PARAMS);
   
    cursor = cursor < thiz->size ? cursor : thiz->size;
    if(darray_expand(thiz,1) == RET_OK)
    {
        size_t i = 0;
        for(i = thiz->size; i > cursor; i--)
        {
            thiz->data[i] = thiz->data[i-1];
        }
        thiz->data[cursor] = data;
        thiz->size++;

        ret = RET_OK;
    }
    return ret;
}

/*************************************

*     压缩数组,在空闲的空间到了一定的数量的时候,就进行压缩,

*当使用空间小于分配的空间的一半的时候,就将当前的空间缩小为1.5倍已使用的空间。

*计算公式为alloc_size = (thiz->size >>1) +thiz->size

*这样就可以避免一些环境中没有浮点运算,以及浮点运算可能造成的误差~~thiz->alloc_size > MIN_PRE_ALLOCATE_NR

*是为了防止到了一定时候,压缩过于频繁

*

*

********************************************/


static Ret darray_shrink(DArray* thiz)
{
    return_val_if_fail(thiz != NULL, RET_INVALID_PARAMS);
    if((thiz->size < (thiz->alloc_size >> 1)) && (thiz->alloc_size > MIN_PRE_ALLOCATE_NR ))
    {
        size_t alloc_size = (thiz->size >>1) +thiz->size;
        void** data = (void **)realloc(thiz->data,sizeof(void*)*alloc_size);
        if(data != NULL)
        {
            thiz->alloc_size = alloc_size;
            thiz->data =data;
        }
    }
    return RET_OK;
}

 

 

//根据下标删除某个元素,先删,再定容。
Ret darray_delete(DArray* thiz, size_t index)
{
    size_t i=0;
    Ret ret = RET_OK;

    return_val_if_fail(thiz != NULL && thiz->size > index, RET_INVALID_PARAM);

    darray_destroy_data(thiz,thiz->data[index]);
    for(i = index; (i+1) < thiz->data->size; ++i)
    {
        thiz->data[i] = thiz->data[i+1];
    }
    thiz->size--;
   
    darray_shrink(thiz);
    return RET_OK;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值