文章标题

来源:互联网 发布:大数据股票龙头股 编辑:程序博客网 时间:2024/06/12 00:36

通用动态数组学习笔记

通用动态数组,这儿是我的笔记,希望大家可以友好交流!!谢谢#__#今天开始学习动态数组的设计,有了前面的经验还算比较快的,也借鉴了CSDN的大神的想法!(想哭,感觉后面更加艰难,非科班自学很痛苦,还是好好务实打基础吧)。
struct darray{    void** data;//整个数据域的首地址    int Capacity;//动态数组的现有容量    int NowLen;//数组的有效长度,正常情况NowLen<Capacity    OPERATE Compare;//函数指针变量    OPERATE Printf;};
首先给出动态数组的定义,再设计结构的时候,我们无需关心用户的数据是怎么样的,只需要管我们做的事。所以我们用void*指针来保存待存储数据的地址,而我们其实更加在乎的是存储地址的一整片区域的首地址,这样我们可以在后面通过(假设A是链表)A->data[i]来标记某个数据的指针。一般的我们初始化的时候,会优先给数组分配一定的空间,通过da->data = (void **)malloc(sizeof(void*)*INIT_LENGTH)来分配,INIT_LENGTH是自定义的宏,可以是5,10等等。每次插入数据的时候,通过判断A->NewLen == A->Capacity决定是否需要对数组进行扩展,扩展的逻辑如下:
if((da->data = (void **)realloc(da->data,sizeof(void*)*Toexpand)) != NULL)    {        for(i = da->Capacity;i < Toexpand; i++)        {            da->data[i] = NULL;        }        da->Capacity = Toexpand;        return true;    }
删除的时候我们也要注意,记住之前讲过的,在哪层malloc的就应该在哪里free,所以数据从结构层我们只管A(前面说A是struct darray的指针

)的释放和data的释放,对于A->data的释放,我们在删除一个或几个数据不做处理,只在删除所有数据时,在释放A前删除A->data即可。

对于自定义的类型用户一般都会自定义一个打印的函数供回调,所以我们在动态数组中加入了函数指针,还有倘若用户自定义的数据也是需要动态分配的话,就还要自定义一个释放函数供回调,所以有A->my_free指针;大概的思路就是这样,然后我把实现代码记录在这里:这个是.h文件
#ifndef _DONGTAISHUZU_H_#define _DONGTAISHUZU_H_#include<stdlib.h>#include<memory.h>#define INIT_LENGTH 3typedef (*OPERATE)();typedef enum{    false = 0,    true,}bool;/**动态数组的声明,定义在.c中*/struct darray;typedef struct darray Darray;typedef struct darray* Darray_T;/**接口*/Darray_T Darray_Init(Darray_T DA);bool  Darray_Expand(Darray_T DA);bool Darray_PushBack(Darray_T DA,void* data);/**在指定位置插入*/bool Darray_InsertByIndex(Darray_T DA,int index,void* data);/**删除指定位置的元素*/bool Darray_DeleteByIndex(Darray_T DA,int index,OPERATE op,void ** data);int Darray_Length(Darray_T DA);int Darray_Capacity(Darray_T DA);#endif
接着是实现接口
#include "dongtaishuzu.h"/**********这么设计真的好像和用户去区无关了为了适应更多的数据类型,我们存储的只是数据的的地址(void *)其实我们更关注的是数据存储的那块首地址,因此我们使用void ** 来存储数据存储区域的首地址;********************************/struct darray{    void** data;    int Capacity;    int NowLen;    OPERATE Compare;    OPERATE Printf;};Darray_T Darray_Init(Darray_T DA){    Darray_T da = DA;    int i= 0;    if((da = (Darray_T)malloc(sizeof(Darray))) == NULL) return NULL;    if((da->data = (void **)malloc(sizeof(void*)*INIT_LENGTH)) != NULL)    {        da->Capacity = INIT_LENGTH;        da->NowLen = 0;        da->Compare = NULL;        da->Printf =NULL;        for(i=0;i<INIT_LENGTH;i++)        {            da->data[i] = NULL;        }        return da;    }    return NULL;}bool Darray_PushBack(Darray_T DA,void* data)//相当于追加{    Darray_T da = DA;    if(da == NULL || data == NULL) return false;    if(da->NowLen == da->Capacity)    {        if(Darray_Expand(da))        {           da->data[da->NowLen] = data;            da->NowLen++;            return true;        }        else return false;    }    /*****没有超过容量时*****/    da->data[da->NowLen] = data;    da->NowLen++;    return true;}bool Darray_InsertByIndex(Darray_T DA,int index,void* data){    Darray_T da = DA;    int i = 0;    if(da == NULL) return false;    if(da->NowLen == da->Capacity)    {        if(Darray_Expand(da))        {            for(i = da->NowLen;i > index;i--)            {                da->data[i] = da->data[i-1];            }            da->data[index] = data;            da->NowLen++;            return true;        }        return false;    }    for(i = da->NowLen;i > index;i--)    {        da->data[i] = da->data[i-1];    }        da->data[index] = data;        da->NowLen++;        return true;}bool  Darray_Expand(Darray_T DA){    Darray_T da = DA;    int Toexpand = DA->Capacity + INIT_LENGTH,i=0;    if((da->data = (void **)realloc(da->data,sizeof(void*)*Toexpand)) != NULL)    {        for(i = da->Capacity;i < Toexpand; i++)        {            da->data[i] = NULL;        }        da->Capacity = Toexpand;        return true;    }    return false;}/**删除元素后将数据返回供用户处理*/bool Darray_DeleteByIndex(Darray_T DA,int index,OPERATE op,void ** data){    int i = 0;    Darray_T da = DA;    if(da == NULL) return false;    if(index > da->NowLen) return false;    *data = da->data[index];    for(i = index; i < da->NowLen; i++)    {        da->data[i] = da->data[i+1];    }    if(op!=NULL) op(*data);     da->NowLen--;    return true;}/**为每个元素执行op操作*/void Darray_Foreach(Darray_T DA,OPERATE op,void* sxw){    Darray_T da = DA;    int i = 0;    for(i = 0; i < da->NowLen; i++)    {        op(da->data[i],sxw);    }}/**销毁整个数组*/bool Darray_DeleteAll(Darray_T DA,OPERATE op,void** data){    Darray_T da = DA;    int i = 0;    if(da == NULL) return false;    while(Darray_Length(da)!=0)    {        Darray_DeleteByIndex(da,Darray_Length(da),op,data);    }    Darray_DeleteByIndex(da,Darray_Length(da),op,data);    free(da->data);    free(da);    return true;}int Darray_Length(Darray_T DA){    return DA->NowLen;}int Darray_Capacity(Darray_T DA){    return DA->Capacity;}
后来做了几个实验,把int,string,还有结构体等类型都试了一遍,都没有问题,至此应该完成了动态数组的实现,当然数组肯定离不开排序,所以我这里不一一列举我的实验,只将存整数的实验记下来,下次学的快的话,把排序弄上来,恰好和整数结合起来(嘿嘿)。这里是主函数,运行时test_ForInt()即可,其他可以相应头文件删除即可。
#include "dongtaishuzu.h"#include<stdio.h>#include<stdlib.h>#include "vector_forStructInt.h"#include "vector_forstr.h"#include "vector_forint.h"#include "vector_forStructStr.h"int main(){    test_StructInt();    test_StructStr();    test_ForStr();    test_ForInt();    return 0;}
vector_forint.h
#ifndef _VECTOR_FORINT_H_#define _VECTOR_FORINT_H_#include <stdlib.h>#include "dongtaishuzu.h"void test_ForInt();void my_IntPrintf(int *d);#endif 
vector_forint.c
#include"vector_forint.h"void test_ForInt(){    #define N 7    int sco[N] = {10,9,6,8,7,3,4};    int a = 99;    void *data = NULL;    int i = 0;    Darray_T darray = Darray_Init(darray);    printf("第四次实验这是测试存放放非动态分配的整数\n");    for(i=0;i<N;i++)    {        if(Darray_PushBack(darray,&sco[i]))        {            printf("%d\n",i);        }    }     printf("\n现在的容量是%d\n",Darray_Capacity(darray));     printf("\n现在的长度是%d\n",Darray_Length(darray));     printf("\n现在数组的内容是\n");     Darray_Foreach(darray,my_IntPrintf,NULL);    printf("\n从第2个位置插入后\n");    Darray_InsertByIndex(darray,2,&a);    Darray_Foreach(darray,my_IntPrintf,NULL);    printf("\n从第2个位置删除后\n");    Darray_DeleteByIndex(darray,2,NULL,(void **)&data);    printf("\n%d\n",*((int*)data));    Darray_Foreach(darray,my_IntPrintf,NULL);    printf("\n彻底清楚后\n");    Darray_DeleteAll(darray,NULL,(void **)&data);    Darray_Foreach(darray,my_IntPrintf,NULL);}void my_IntPrintf(int *d){    printf("元素%d\t",*d);}

到这就没了,其他的就不粘贴了,哈哈哈

原创粉丝点击