文章标题
来源:互联网 发布:大数据股票龙头股 编辑:程序博客网 时间: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);}
到这就没了,其他的就不粘贴了,哈哈哈
阅读全文
1 0
- 文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题 文章标题 文章标题 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 有两队选手每队5人进行一对一的比赛,甲队为A、B、C、D、E,乙队为J、K、L、M、N,经过抽签决定比赛对手名单。规定A不和J比赛, M不和D及E比赛。列出所有可能的比赛名单。 提示:先固定甲队,A在
- hdoj-2097Sky数(进制转换)
- 文章标题
- vue设置请求时的header
- 我使用过的Linux命令之sftp
- 文章标题
- 7.3 异常类
- VIM/VI
- spring boot本地事物管理和分布式事物管理(五)
- linux 用户权限设置示例
- Thinkphp的list_to_tree 实现无限级分类列出所有节点
- fetch与formdata的故事
- java 实现Mybatis入门
- vue-resource emulateJSON