C语言实现基本动态数组:
1 #include <stdio.h> 2 #include <malloc.h> 3 #include <string.h> 4 #define INIT_CAP 4 //初始分配空间大小 5 #define _Bool unsigned short 6 typedef int ADT; 7 typedef struct{ 8 unsigned size; //数组元素数量 9 unsigned capacity; //容量大小 10 ADT *begpos, *endpos; //初始位置指针,末尾位置指针 11 }Arr, *pArr; 12 13 pArr Init(pArr p){ 14 p -> begpos = (ADT*)malloc(sizeof(ADT) * INIT_CAP); //申请 每个元素字节数*初始分配存储单元个数 大小的空间 15 p -> size = 0; //初始个数置为0 16 p -> capacity = INIT_CAP; //初始容量为默认大小 17 p -> endpos = p -> begpos; //初始化尾指针与首指针位置相同 18 } 19 20 _Bool Extend(pArr p){ //扩展数组容量大小 21 ADT* newspace = (ADT*)malloc(sizeof(ADT) * p -> capacity * 2); //申请原来空间两倍大小的空间 22 if(newspace == NULL) return 0; //申请失败返回0 23 memcpy(newspace, p -> begpos, sizeof(ADT) * p -> capacity); //将原来数组元素复制到新数组 24 free(p -> begpos); //释放原数组空间 25 p -> begpos = newspace; //首指针指向新数组首部 26 p -> capacity *= 2; //容量扩大2倍 27 p -> endpos = p -> begpos + p -> size; //尾指针更新 28 return 1; 29 } 30 31 ADT* Add(const pArr p, const ADT value){ //添加新元素 32 if(p -> capacity == p -> size){ //判断空间是否已满 33 if(!Extend(p)){ //扩展新空间 34 printf("add %d failed! Maybe have memery not enough.\n", value); 35 return NULL; 36 } 37 } 38 *p -> endpos = value; //在尾指针处放置新元素 39 ++ p -> endpos; //尾指针后移 40 ++ p -> size; //元素数量增加 41 printf("Add number: %d, Size now: %d/%d\n", value, p -> size, p->capacity); 42 } 43 44 void Clear(const pArr p){ //清空数组 45 p -> size = 0; 46 p -> endpos = p -> begpos; 47 } 48 49 void Desdroy(const pArr p){ //销毁数组 50 free(p -> begpos); 51 } 52 53 void Traverse(const pArr p){ //遍历数组 54 if(!p -> size){ 55 printf("Empty!\n"); 56 return; 57 } 58 printf("\nTraverse: "); 59 ADT* beg = p -> begpos; 60 while(beg != p -> endpos){ 61 printf("%d ", *beg); 62 ++ beg; 63 } 64 printf("\n"); 65 } 66 67 _Bool less(const ADT v, const ADT aim){ //条件函数(小于某值) 68 return v < aim; 69 } 70 _Bool grater(const ADT v, const ADT aim){ //条件函数(大于某值) 71 return v > aim; 72 } 73 74 unsigned Remove(const pArr p, const int aim){ //删除数组值为 aim 的元素 75 unsigned count = 0; 76 ADT* w = p -> begpos, *r = p -> begpos; //设置两个指针初始指向首地址 77 for(; r!=p -> endpos; ++r){ //通过两个指针移动删除某值 78 if(*r == aim){ 79 ++ count; 80 -- p -> size; 81 } 82 else *w++ = *r; 83 } 84 p -> endpos = w; 85 return count; //返回删除个数 86 } 87 88 unsigned Remove_if(const pArr p, const ADT arg, _Bool(* con)(ADT, ADT)){ //条件删除指定元素 89 unsigned count = 0; 90 ADT* w = p -> begpos, *r = p -> begpos; 91 for(; r!=p -> endpos; ++r){ 92 if(con(*r, arg)){ 93 ++ count; 94 -- p -> size; 95 } 96 else *w++ = *r; 97 } 98 p -> endpos = w; 99 return count; 100 } 101 102 int main(){ 103 Arr array; 104 Init(&array); 105 106 Add(&array, 3); 107 Add(&array, 6); 108 Add(&array, 2); 109 Add(&array, 1); 110 Add(&array, 5); 111 Traverse(&array); 112 Clear(&array); 113 Traverse(&array); 114 115 Desdroy(&array); 116 Init(&array); 117 Add(&array, 4); 118 Add(&array, 4); 119 Add(&array, 3); 120 Add(&array, 8); 121 Add(&array, 4); 122 Traverse(&array); 123 printf("Has removed %d numbers.\n", Remove_if(&array, 5, less)); //删除小于5的所有元素 124 Traverse(&array); 125 126 return 0; 127 }
测试输出:
Add number: 3, Size now: 1/4 Add number: 6, Size now: 2/4 Add number: 2, Size now: 3/4 Add number: 1, Size now: 4/4 Add number: 5, Size now: 5/8 Traverse: 3 6 2 1 5 Empty! Add number: 4, Size now: 1/4 Add number: 4, Size now: 2/4 Add number: 3, Size now: 3/4 Add number: 8, Size now: 4/4 Add number: 4, Size now: 5/8 Traverse: 4 4 3 8 4 Has removed 4 numbers. Traverse: 8